limixbot 0.3.18 → 0.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{ActivityPanel-CiVMRvA-.js → ActivityPanel-D0V5shGd.js} +1 -1
- package/dist/assets/{App-B612vSUv.js → App-DXv-5ZTc.js} +8 -8
- package/dist/assets/{AppEventEditor-Id4kTgLa.js → AppEventEditor-mJOa46It.js} +1 -1
- package/dist/assets/{BotSettingsDialog-DdTKCtEA.js → BotSettingsDialog-DOF82zFt.js} +1 -1
- package/dist/assets/{BrowserPanel-thqBHOQl.js → BrowserPanel-Cbp7LssC.js} +1 -1
- package/dist/assets/{BrowserProfilesManager-J8hqmwv5.js → BrowserProfilesManager-LC4INRs7.js} +1 -1
- package/dist/assets/{CloudAddDialog-BNroQCqt.js → CloudAddDialog-DywJ4txo.js} +1 -1
- package/dist/assets/{ComputerFilesPane-BXUVfqmc.js → ComputerFilesPane-BjzS9ZTa.js} +1 -1
- package/dist/assets/{ComputerPanel-BGE1fw6l.js → ComputerPanel-DGPKl9mx.js} +2 -2
- package/dist/assets/{DataPanel-CQWnhToC.js → DataPanel-CowhAHcc.js} +1 -1
- package/dist/assets/{FilesView-CYEcHPlb.js → FilesView-Di6bZ56Z.js} +1 -1
- package/dist/assets/{GrokMoveDialog-GD3YuWYi.js → GrokMoveDialog-BXwNEoZf.js} +1 -1
- package/dist/assets/{InspectorPanel-B_-Xse3K.js → InspectorPanel-gvViZQrp.js} +1 -1
- package/dist/assets/{KeyboardShortcutsModal-BAsXL39B.js → KeyboardShortcutsModal-C6gDEGpK.js} +1 -1
- package/dist/assets/{LiveDesktop-CLu-oUdB.js → LiveDesktop-BklBBcgn.js} +1 -1
- package/dist/assets/{LocalVmWorkspace-CrRurzrY.js → LocalVmWorkspace-D1xWHo1G.js} +1 -1
- package/dist/assets/{MacLocalControl-Jp0LjT_C.js → MacLocalControl-BfwVFZRa.js} +1 -1
- package/dist/assets/{MarkdownFilePreview-ceD2tKz1.js → MarkdownFilePreview-Cy-DECsV.js} +1 -1
- package/dist/assets/{NewBotDialog-C_M8t6Ri.js → NewBotDialog-CRCIYvfv.js} +1 -1
- package/dist/assets/{PhoneAppDialog-VezYkaXY.js → PhoneAppDialog-CmcHLaYr.js} +1 -1
- package/dist/assets/{PluginsPanel-Bcsv8kad.js → PluginsPanel-C46LU5EJ.js} +1 -1
- package/dist/assets/{ProIntroduction-BeqDgqS2.js → ProIntroduction-DuPsMUld.js} +1 -1
- package/dist/assets/{RemoteAgentSettingsPanel-Gc-vYBxb.js → RemoteAgentSettingsPanel-BauS0Y0t.js} +1 -1
- package/dist/assets/{RoomPanel-DBJbvMf1.js → RoomPanel-BiaRLuVx.js} +1 -1
- package/dist/assets/{RoutinesPage-C8O6H_m9.js → RoutinesPage-BeldL46G.js} +1 -1
- package/dist/assets/{SettingsModal-C28PTR8i.js → SettingsModal-DBLLYSR2.js} +1 -1
- package/dist/assets/{ShareTeamDialog-CSfZehTH.js → ShareTeamDialog-uEP_ILfa.js} +1 -1
- package/dist/assets/{SignedInSites-BaywJMFM.js → SignedInSites-BgqjFXnz.js} +1 -1
- package/dist/assets/{TeamLibraryPanel-DNEOuAa6.js → TeamLibraryPanel-Bd7HFgTR.js} +1 -1
- package/dist/assets/{TeamMapPage-CRIOLuDD.js → TeamMapPage-DslnWFG2.js} +1 -1
- package/dist/assets/{TriggersPage-D_HBWqEe.js → TriggersPage-BK73CwJR.js} +1 -1
- package/dist/assets/{VisibilitySection-C_Lg0Sxb.js → VisibilitySection-CZVuYCfP.js} +1 -1
- package/dist/assets/{WebhookTrigger-Cpp-PlPP.js → WebhookTrigger-DXr8EYFe.js} +1 -1
- package/dist/assets/{WorksOnGrid-DxsV4-UT.js → WorksOnGrid-DJJIaPGa.js} +1 -1
- package/dist/assets/{core-DUBJa6se.js → core-DIFUUeI5.js} +1 -1
- package/dist/assets/{import-name-w5H0_aIa.js → import-name-CFjzsLGq.js} +1 -1
- package/dist/assets/{index-CJ71uySw.js → index-BBObcTo5.js} +2 -2
- package/dist/assets/{index-B6hNR0We.js → index-D2Hr2dxf.js} +1 -1
- package/dist/assets/{mcp-servers-DT3QTM7h.js → mcp-servers-5_CMZE0a.js} +1 -1
- package/dist/assets/{new-bot-Wr7msRe_.js → new-bot-BNUINkXW.js} +1 -1
- package/dist/assets/{org-library-BTDDXkLR.js → org-library-D71rjidw.js} +1 -1
- package/dist/assets/{package-format-ByePhvES.js → package-format-Bc1BWLbR.js} +1 -1
- package/dist/assets/{remote-desktop-panel-CMGlHR7t.js → remote-desktop-panel-CG1BY1IR.js} +1 -1
- package/dist/index.html +1 -1
- package/dist-server/index.js +675 -673
- package/dist-server/openmausbot.js +240 -236
- package/dist-server/package.json +1 -1
- package/dist-server/pair-cli.js +240 -236
- package/dist-server/server/drivers/antigravity.js +11 -0
- package/dist-server/server/limix-agy-cli.js +65 -0
- package/package.json +1 -1
package/dist-server/pair-cli.js
CHANGED
|
@@ -126,7 +126,7 @@ sha384_base64url,sha512_hex,sha512_base64,sha512_base64url,init_regexes=__esm({"
|
|
|
126
126
|
guid=/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/,uuid=version2=>version2?new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version2}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`):/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/,uuid4=uuid(4),uuid6=uuid(6),uuid7=uuid(7),email=/^(?:[A-Za-z0-9_'+\-]+\.)*[A-Za-z0-9_'+\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/,
|
|
127
127
|
html5Email=/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,rfc5322Email=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,unicodeEmail=/^[^\s@"]{1,64}@[^\s@]{1,255}$/u,idnEmail=unicodeEmail,browserEmail=/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
|
|
128
128
|
_emoji="^(?=[\\s\\S]*[\\p{Extended_Pictographic}\\p{Regional_Indicator}\\u20E3])[\\p{Extended_Pictographic}\\p{Emoji_Component}]+$";ipv4=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,ipv6=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/,
|
|
129
|
-
mac=
|
|
129
|
+
mac=delimiter11=>{let escapedDelim=escapeRegex(delimiter11??":");return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`)},cidrv4=/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/,cidrv6=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,
|
|
130
130
|
base64=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,base64url=/^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2,3})?$/,hostname=/^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/,domain=/^(?=.{1,253}$)([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,63}$/,httpProtocol=/^https?$/,e164=/^\+[1-9]\d{6,14}$/,creditCard=/^\d(?:[ -]?\d){11,18}$/,currencyCode=/^(?:AED|AFN|ALL|AMD|AOA|ARS|AUD|AWG|AZN|BAM|BBD|BDT|BHD|BIF|BMD|BND|BOB|BOV|BRL|BSD|BTN|BWP|BYN|BZD|CAD|CDF|CHE|CHF|CHW|CLF|CLP|CNY|COP|COU|CRC|CUP|CVE|CZK|DJF|DKK|DOP|DZD|EGP|ERN|ETB|EUR|FJD|FKP|GBP|GEL|GHS|GIP|GMD|GNF|GTQ|GYD|HKD|HNL|HTG|HUF|IDR|ILS|INR|IQD|IRR|ISK|JMD|JOD|JPY|KES|KGS|KHR|KMF|KPW|KRW|KWD|KYD|KZT|LAK|LBP|LKR|LRD|LSL|LYD|MAD|MDL|MGA|MKD|MMK|MNT|MOP|MRU|MUR|MVR|MWK|MXN|MXV|MYR|MZN|NAD|NGN|NIO|NOK|NPR|NZD|OMR|PAB|PEN|PGK|PHP|PKR|PLN|PYG|QAR|RON|RSD|RUB|RWF|SAR|SBD|SCR|SDG|SEK|SGD|SHP|SLE|SOS|SRD|SSP|STN|SVC|SYP|SZL|THB|TJS|TMT|TND|TOP|TRY|TTD|TWD|TZS|UAH|UGX|USD|USN|UYI|UYU|UYW|UZS|VED|VES|VND|VUV|WST|XAD|XAF|XAG|XAU|XBA|XBB|XBC|XBD|XCD|XCG|XDR|XOF|XPD|XPF|XPT|XSU|XTS|XUA|XXX|YER|ZAR|ZMW|ZWG)$/,
|
|
131
131
|
iban=/^[A-Z]{2}(?!00|01|99)\d{2}[A-Z0-9]{11,30}$/,dateSource="(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))";date=anchor(dateSource);anyString=/^[\s\S]{0,}$/,string=params=>{let regex=params?`[\\s\\S]{${params?.minimum??0},${params?.maximum??""}}`:"[\\s\\S]*";return new RegExp(`^${regex}$`)},bigint=/^-?\d+n?$/,integer=/^-?\d+$/,number=
|
|
132
132
|
/^-?\d+(?:\.\d+)?$/,boolean=/^(?:true|false)$/i,_null=/^null$/i,_undefined=/^undefined$/i,lowercase=/^[^A-Z]*$/,uppercase=/^[^a-z]*$/,hex=/^[0-9a-fA-F]*$/;md5_hex=/^[0-9a-fA-F]{32}$/,md5_base64=fixedBase64(22,"=="),md5_base64url=fixedBase64url(22),sha1_hex=/^[0-9a-fA-F]{40}$/,sha1_base64=fixedBase64(27,"="),sha1_base64url=fixedBase64url(27),sha256_hex=/^[0-9a-fA-F]{64}$/,sha256_base64=fixedBase64(43,"="),sha256_base64url=fixedBase64url(43),sha384_hex=/^[0-9a-fA-F]{96}$/,sha384_base64=fixedBase64(
|
|
@@ -2947,12 +2947,12 @@ mtimeMs>DOWNLOAD_TIMEOUT_MS3&&rmSync13(part,{recursive:!0,force:!0})}let tag2=ra
|
|
|
2947
2947
|
platform])))throw new Error("the Chrome archive did not hold the browser; nothing was installed");return rmSync13(directory,{recursive:!0,force:!0}),renameWithRetry(staging,directory),executable}finally{rmSync13(archive,{force:!0}),rmSync13(staging,{recursive:!0,force:!0})}}var CHROME_FOR_TESTING_VERSION,PINS,EXECUTABLES,DOWNLOAD_TIMEOUT_MS3,EXTRACT_TIMEOUT_MS,extractZip,installs,init_install=__esm({"server/browser/chrome/install.ts"(){"use strict";init_atomic();CHROME_FOR_TESTING_VERSION="153.0\
|
|
2948
2948
|
.8010.47",PINS={"darwin-arm64":{platform:"mac-arm64",bytes:190878359,sha256:"939ef9dc3aa74240c929d793e123edab0fda89c5a9cfeb029686c34141d2ed58"},"linux-x64":{platform:"linux64",bytes:195709628,sha256:"89778cbf7a852726b6f51649b2586b894c00737e81f8031733721560d21bbea7"},"linux-arm64":{platform:"linux-arm64",bytes:195919275,sha256:"ef3d2fea85e675ba8e9a7894c0be4595e5130659a9ac95e04c6064ed09f411da"}},EXECUTABLES={"mac-arm64":"chrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome f\
|
|
2949
2949
|
or Testing","mac-x64":"chrome-mac-x64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing",win64:"chrome-win64/chrome.exe",linux64:"chrome-linux64/chrome","linux-arm64":"chrome-linux-arm64/chrome"},DOWNLOAD_TIMEOUT_MS3=20*6e4,EXTRACT_TIMEOUT_MS=10*6e4;extractZip=(archive,directory)=>new Promise((resolve35,reject)=>{mkdirSync15(directory,{recursive:!0,mode:448});let[file2,args]=process.platform==="win32"?[win323.join(process.env.SystemRoot??"C:\\Windows","System32","tar.exe"),[
|
|
2950
|
-
"-xf",archive,"-C",directory]]:["unzip",["-q",archive,"-d",directory]];execFile8(file2,args,{timeout:EXTRACT_TIMEOUT_MS,windowsHide:!0,maxBuffer:16*1024*1024},error62=>{if(error62){let noUnzip=file2==="unzip"&&error62.code==="ENOENT";reject(new Error(noUnzip?"the Chrome archive could not be unpacked: check that unzip is installed and on the server's PATH (Debian/Ubuntu: sudo apt-get install unzip)":`the Chrome archive could not be unpacked: ${error62.message}`))}else resolve35()})}),installs=new Map}});import{spawnSync as spawnSync4}from"node:child_process";import{existsSync as existsSync21,readdirSync as readdirSync11}from"node:fs";import{homedir as homedir10}from"node:os";import{posix as posix5,resolve as resolve12,win32 as win324}from"node:path";function isHeadlessShell(path3){return/chrome-headless-shell/iu.test(path3)}function installedGoogleChrome(host2){let{join:
|
|
2951
|
-
ome");registered&&candidates.push(
|
|
2952
|
-
root&&candidates.push(
|
|
2953
|
-
le.Chrome.plist"))}return host2.platform==="win32"?host2.registryKeyExists(WINDOWS_POLICIES):host2.platform==="linux"?host2.list(LINUX_POLICIES).some(name=>name.endsWith(".json")):!1}function agentBrowserChrome(host2){let layout=AGENT_BROWSER_LAYOUTS[host2.platform];if(!layout)return null;let{join:
|
|
2954
|
-
map(version2=>
|
|
2955
|
-
return cached4(
|
|
2950
|
+
"-xf",archive,"-C",directory]]:["unzip",["-q",archive,"-d",directory]];execFile8(file2,args,{timeout:EXTRACT_TIMEOUT_MS,windowsHide:!0,maxBuffer:16*1024*1024},error62=>{if(error62){let noUnzip=file2==="unzip"&&error62.code==="ENOENT";reject(new Error(noUnzip?"the Chrome archive could not be unpacked: check that unzip is installed and on the server's PATH (Debian/Ubuntu: sudo apt-get install unzip)":`the Chrome archive could not be unpacked: ${error62.message}`))}else resolve35()})}),installs=new Map}});import{spawnSync as spawnSync4}from"node:child_process";import{existsSync as existsSync21,readdirSync as readdirSync11}from"node:fs";import{homedir as homedir10}from"node:os";import{posix as posix5,resolve as resolve12,win32 as win324}from"node:path";function isHeadlessShell(path3){return/chrome-headless-shell/iu.test(path3)}function installedGoogleChrome(host2){let{join:join106}=paths(host2.platform),candidates=[];if(host2.platform==="darwin"){let registered=host2.appForBundleId("com.google.Chr\
|
|
2951
|
+
ome");registered&&candidates.push(join106(registered,MAC_CHROME_BINARY)),candidates.push(join106("/Applications/Google Chrome.app",MAC_CHROME_BINARY),join106(host2.home,"Applications/Google Chrome.app",MAC_CHROME_BINARY))}else if(host2.platform==="win32"){for(let hive of["HKLM","HKCU"]){let registered=host2.registryValue(`${hive}\\${WINDOWS_APP_PATHS}`);registered&&candidates.push(registered.replace(/^"|"$/gu,""))}for(let root of[host2.env.ProgramFiles,host2.env["ProgramFiles(x86)"],host2.env.LOCALAPPDATA])
|
|
2952
|
+
root&&candidates.push(join106(root,"Google","Chrome","Application","chrome.exe"))}else host2.platform==="linux"&&candidates.push(LINUX_CHROME);return candidates.find(candidate=>host2.exists(candidate))??null}function chromePolicyManaged(host2){let{basename:basename19,join:join106}=paths(host2.platform);if(host2.platform==="darwin"){let user=host2.env.USER||basename19(host2.home);return host2.exists(join106(MAC_POLICIES,"com.google.Chrome.plist"))||host2.exists(join106(MAC_POLICIES,user,"com.goog\
|
|
2953
|
+
le.Chrome.plist"))}return host2.platform==="win32"?host2.registryKeyExists(WINDOWS_POLICIES):host2.platform==="linux"?host2.list(LINUX_POLICIES).some(name=>name.endsWith(".json")):!1}function agentBrowserChrome(host2){let layout=AGENT_BROWSER_LAYOUTS[host2.platform];if(!layout)return null;let{join:join106}=paths(host2.platform),browsers=join106(host2.home,".agent-browser","browsers");return host2.list(browsers).filter(name=>name.startsWith("chrome-")).sort((a2,b3)=>b3.localeCompare(a2,void 0,{numeric:!0})).
|
|
2954
|
+
map(version2=>join106(browsers,version2,layout)).find(candidate=>host2.exists(candidate))??null}function engineFindsLinuxBrowser(host2){let{join:join106}=posix5;if((host2.enginePath?.()??host2.env.PATH??"").split(":").filter(Boolean).some(directory=>LINUX_ENGINE_BROWSERS.some(name=>host2.exists(join106(directory,name)))))return!0;let cached4=(directory,prefix)=>host2.list(directory).some(name=>name.startsWith(prefix)&&LINUX_CACHE_EXECUTABLES.some(executable=>host2.exists(join106(directory,name,executable))));
|
|
2955
|
+
return cached4(join106(host2.env.PUPPETEER_CACHE_DIR||join106(host2.home,".cache","puppeteer"),"chrome"),"linux")||cached4(host2.env.PLAYWRIGHT_BROWSERS_PATH||join106(host2.home,".cache","ms-playwright"),"chromium-")}function resolveChromePlan(host2,engine,options2={}){let{env,platform}=host2;if(env.OMB_BROWSER_LEGACY_SHELL?.trim()==="1")return{kind:"legacy",reason:"OMB_BROWSER_LEGACY_SHELL=1"};let named2=env.OMB_CHROME_PATH?.trim()||env.AGENT_BROWSER_EXECUTABLE_PATH?.trim();if(named2)return isHeadlessShell(
|
|
2956
2956
|
named2)?{kind:"legacy",reason:"the named browser is a headless shell"}:host2.exists(named2)?{kind:"chrome",chrome:{path:paths(platform).isAbsolute(named2)?named2:resolve12(named2),source:"named"},fallback:null}:{kind:"legacy",reason:`${named2} does not exist`};if(!engine?.managed)return{kind:"legacy",reason:"agent-browser was named, so it picks its own browser"};let pin=platform==="linux"&&env.OMB_RESOURCES_PATH?null:chromeForTestingPin(platform,host2.arch),installed=installedGoogleChrome(host2);
|
|
2957
2957
|
if(installed&&!chromePolicyManaged(host2))return{kind:"chrome",chrome:{path:installed,source:"installed"},fallback:pin};if(platform==="linux"&&env.OMB_RESOURCES_PATH)return{kind:"legacy",reason:installed?"Google Chrome here is managed by an organization":"Google Chrome is not installed"};let own4=agentBrowserChrome(host2);if(own4)return{kind:"chrome",chrome:{path:own4,source:"agent-browser"},fallback:null};if(pin){let executable=chromeForTestingExecutable(host2.dataDir,pin);return host2.exists(executable)?
|
|
2958
2958
|
{kind:"chrome",chrome:{path:executable,source:"downloaded"},fallback:null}:platform==="linux"&&!options2.downloading&&engineFindsLinuxBrowser(host2)?{kind:"legacy",reason:"agent-browser found a browser on this server"}:{kind:"download",pin}}return{kind:"legacy",reason:installed?"Google Chrome here is managed by an organization":"no Chrome is installed and none is pinned for this platform"}}function registryQuery(args){let result2=spawnSync4("reg",["query",...args],{encoding:"utf8",timeout:5e3,windowsHide:!0});
|
|
@@ -4050,22 +4050,26 @@ runtimeDirectory,asset.harness.name),source:"managed",version:asset.version};awa
|
|
|
4050
4050
|
`,{flag:"wx",mode:384});try{await retryOnWindowsFileLock(()=>rename3(runtimeDirectory,destination))}catch(error62){if(!await completedRelease(destination,asset))throw error62}let installed=await completedRelease(destination,asset);if(!installed)throw new Error("The installed Antigravity runtime is incomplete.");return installed}catch(error62){throw failed2=!0,error62}finally{try{await retryOnWindowsFileLock(()=>rm4(staging,{recursive:!0,force:!0}))}catch(cleanupError){let detail=cleanupError instanceof
|
|
4051
4051
|
Error?cleanupError.message:String(cleanupError);console.warn(`antigravity: could not remove the install folder ${staging} (${detail})${failed2?"":"; the install itself succeeded"}`)}}}function installAntigravityRuntime(options2={}){let key2=runtimeRoot(options2.baseDir),existing=installs2.get(key2);if(existing)return existing;let running4=installOnce3(options2).finally(()=>installs2.delete(key2));return installs2.set(key2,running4),running4}function antigravityManagedInstallAvailable(){return resolveAntigravityReleaseAsset()!==
|
|
4052
4052
|
null}var FREE_SPACE_MARGIN,DOWNLOAD_TIMEOUT_MS4,STAGING_PREFIX2,wait,INSTALL_RECORD,AntigravitySetupError,installs2,init_antigravity_runtime=__esm({"server/drivers/antigravity-runtime.ts"(){"use strict";init_config3();init_engine_roots();init_zip_archive();init_env_path();init_antigravity_release();FREE_SPACE_MARGIN=256*1024*1024,DOWNLOAD_TIMEOUT_MS4=45*6e4,STAGING_PREFIX2=".install-";wait=ms2=>new Promise(resolve35=>setTimeout(resolve35,ms2));INSTALL_RECORD=".install-complete.json",AntigravitySetupError=
|
|
4053
|
-
class extends Error{status=409;constructor(message5){super(message5),this.name="AntigravitySetupError"}},installs2=new Map}});
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
state
|
|
4063
|
-
|
|
4053
|
+
class extends Error{status=409;constructor(message5){super(message5),this.name="AntigravitySetupError"}},installs2=new Map}});import{existsSync as existsSync28,mkdirSync as mkdirSync24,readFileSync as readFileSync29,writeFileSync as writeFileSync13}from"node:fs";import{homedir as homedir15}from"node:os";import{delimiter as delimiter10,join as join56}from"node:path";function findAgyCli(env=process.env){if(env.LIMIX_AGY_CLI==="0")return null;let win=process.platform==="win32",name=win?"agy.exe":"agy",candidates=[],localAppData=env.LOCALAPPDATA??process.env.LOCALAPPDATA;win&&localAppData&&candidates.push(join56(localAppData,
|
|
4054
|
+
"agy","bin",name)),win||candidates.push(join56(homedir15(),".local","bin",name));for(let dir of(env.PATH??env.Path??process.env.PATH??"").split(delimiter10))dir&&candidates.push(join56(dir,name));return candidates.find(candidate=>existsSync28(candidate))??null}function claimedBy(){try{let value=JSON.parse(readFileSync29(claimFile(),"utf8"));return typeof value.instanceId=="string"?value.instanceId:null}catch{return null}}function agyCliFor(instanceId,env=process.env){let cli=findAgyCli(env);if(!cli)
|
|
4055
|
+
return null;let owner=claimedBy();if(owner&&owner!==instanceId)return null;if(!owner)try{mkdirSync24(DATA_DIR,{recursive:!0}),writeFileSync13(claimFile(),JSON.stringify({instanceId,cli,at:new Date().toISOString()}))}catch{return null}return cli}function releaseAgyCli(instanceId){if(claimedBy()===instanceId)try{writeFileSync13(claimFile(),JSON.stringify({instanceId:null}))}catch{}}var claimFile,init_limix_agy_cli=__esm({"server/limix-agy-cli.ts"(){"use strict";init_config3();claimFile=()=>join56(
|
|
4056
|
+
DATA_DIR,"limix-agy-cli.json")}});function normalizeAntigravityTurn(turn,offeredModels2){if(turn.variant!==void 0)return turn;let match=turn.model?.match(/^(.+)-(low|medium|high)$/u);return match&&offeredModels2.includes(match[1])&&!offeredModels2.includes(match[0])?{...turn,model:match[1],variant:match[2]}:turn}function antigravityPermissionMode(fullAuto,approvalMode){return fullAuto||approvalMode==="full"?"yolo":approvalMode==="edits"?"auto_edit":"default"}var STATIC_ANTIGRAVITY_MODELS,managedAsset,support,AcpAntigravityDriver,
|
|
4057
|
+
AntigravityDriver,init_antigravity=__esm({"server/drivers/antigravity.ts"(){"use strict";init_antigravity_account();init_core3();init_antigravity_acp();init_antigravity_runtime();init_antigravity_release();init_antigravity_temp();init_env_path();init_limix_agy_cli();init_bundled();init_manifest();STATIC_ANTIGRAVITY_MODELS=bundledEngineCatalog("antigravity");managedAsset=resolveAntigravityReleaseAsset(),support={driverKind:"antigravityAgent",displayName:"Google Gemini (Antigravity)",get models(){
|
|
4058
|
+
return currentEngineCatalog("antigravity")},defaultCli:"agy",nativeSource:"antigravity.acp",loginNote:"Antigravity needs a Google account \u2014 choose Sign in with Google in engine setup",install:{docsUrl:"https://github.com/agentclientprotocol/registry/tree/main/antigravity-acp",...managedAsset?{managed:{label:"Install official Antigravity",downloadBytes:managedAsset.archiveBytes}}:{}},images:!0,spawnArgs:()=>[],selectModel:{configId:"model"},modelVariants:!0,normalizeSessionSelection:normalizeAntigravityTurn,
|
|
4059
|
+
sessionModelEnv:"AGY_ACP_DEFAULT_MODEL",sessionScopedApproval:!0,resumeMethod:"resume",clientFileSystem:!0,sanitizeToolPayload:!0,resolveCommand:async(env,config3,instanceId)=>{let agyCli=agyCliFor(instanceId,env);if(agyCli)return{command:agyCli,args:["acp"]};let runtime=await resolveAntigravityRuntime(config3.cli,env),profile=await prepareAntigravityProfile({instanceId,runtime,baseEnv:env});return profile.tempDirectory&&scheduleAntigravityTempSweep(instanceId),{command:runtime.executablePath,args:process.
|
|
4060
|
+
platform==="linux"?["--uid="]:[],env:profile.environment}},resolveModels:async(env,config3,instanceId)=>{if(agyCliFor(instanceId,env))return currentEngineCatalog("antigravity");let runtime=await resolveAntigravityRuntime(config3.cli,env),profile=await prepareAntigravityProfile({instanceId,runtime,baseEnv:env});if(!await antigravityProfileAuthenticated(profile))throw new Error(support.loginNote);return probeAntigravityModels({runtime,profile,fallbackDefault:currentEngineCatalog("antigravity").default})},
|
|
4061
|
+
pickAuthMethod:methods=>methods.some(method=>method.id==="oauth-personal")?"oauth-personal":null,authFailure:"fail",requireAuthenticationBeforeSpawn:!0,isAuthenticated:async(env,config3,instanceId)=>{if(agyCliFor(instanceId,env))return!0;try{let runtime=await resolveAntigravityRuntime(config3.cli,env),profile=await prepareAntigravityProfile({instanceId,runtime,baseEnv:env});return antigravityProfileAuthenticated(profile)}catch{return!1}},snapshot:async(env,config3,instanceId)=>{if(agyCliFor(instanceId,
|
|
4062
|
+
env))return{state:"available",version:"Antigravity CLI",authenticated:!0};try{let runtime=await resolveAntigravityRuntime(config3.cli,env),profile=await prepareAntigravityProfile({instanceId,runtime,baseEnv:env});return{state:"available",version:runtime.version,authenticated:await antigravityProfileAuthenticated(profile),account:await antigravityAccount(profile.tokenPath)}}catch(error62){return{state:"unavailable",reason:error62 instanceof Error?error62.message:String(error62)}}},configureSession:async({
|
|
4063
|
+
request:request2,sessionId,config:config3,turn,configOptions:configOptions2})=>{if(!Array.isArray(configOptions2)||!configOptions2.some(option=>option?.id==="mode"))return;let wanted=antigravityPermissionMode(config3.fullAuto,turn.approvalMode),result2=await request2("session/set_config_option",{sessionId,configId:"mode",value:wanted});if((Array.isArray(result2?.configOptions)?result2.configOptions.find(option=>option?.id==="mode")?.currentValue:void 0)!==wanted)throw new Error(`Antigravity did \
|
|
4064
|
+
not apply ${wanted} permission mode.`)}},AcpAntigravityDriver=createAcpDriver(support),AntigravityDriver={...AcpAntigravityDriver,async create(input2){let base2=await AcpAntigravityDriver.create(input2);scheduleAntigravityTempSweep(input2.instanceId),scheduleAntigravityTempSweep(VERIFICATION_TEMP_KEY);let auth=new AntigravityAuthController(()=>{base2.refreshModels?.()}),installFailure,runtimeAndProfile=async()=>{let environment={...process.env,...input2.environment,PATH:augmentedPath()},runtime=await resolveAntigravityRuntime(
|
|
4065
|
+
input2.config.cli,environment),profile=await prepareAntigravityProfile({instanceId:input2.instanceId,runtime,baseEnv:environment});return{runtime,profile}};return{...base2,get models(){return base2.models},get modelsUnconfirmed(){return base2.modelsUnconfirmed},snapshot:async()=>{let snapshot=await base2.snapshot();return snapshot.state==="available"&&(installFailure=void 0),snapshot.state==="unavailable"&&installFailure?{...snapshot,reason:installFailure}:snapshot},...antigravityManagedInstallAvailable()?
|
|
4066
|
+
{installRuntime:async()=>{installFailure=void 0;try{await installAntigravityRuntime({validate:validateAntigravityRuntime})}catch(error62){throw installFailure=error62 instanceof Error?error62.message:String(error62),error62}}}:{},startAuthentication:async()=>{let{runtime,profile}=await runtimeAndProfile();return auth.start(runtime,profile)},completeAuthentication:async(flowId,callbackUrl)=>auth.complete(flowId,callbackUrl),cancelAuthentication:async()=>auth.cancel(),signOut:async()=>{auth.cancel(),
|
|
4067
|
+
await removeAntigravitySignIn(input2.instanceId),releaseAgyCli(input2.instanceId)},dispose:async()=>{auth.cancel(),await base2.dispose()}}}}}});function cliVersionProbe(cli,run6=execCli){let read2=cliVersionReader(cli),pending;return env=>{if(pending)return pending;let deadline=Date.now()+CLI_VERSION_TIMEOUT_MS,attempt=()=>new Promise(resolve35=>{run6(cli,["--version"],{timeout:Math.max(1,deadline-Date.now()),env},(error62,stdout2)=>resolve35({error:error62,stdout:stdout2}))});return pending=(async()=>{let result2=await attempt();return!result2.error&&!result2.stdout.trim()&&Date.now()<deadline&&(result2=await attempt()),read2(result2.error,
|
|
4064
4068
|
result2.stdout)})().finally(()=>{pending=void 0}),pending}}var init_cli_version_probe=__esm({"server/cli-version-probe.ts"(){"use strict";init_procs()}});function claudeAuthStatus(cli,env,run6=execCli){return new Promise(resolve35=>{run6(cli,["auth","status","--json"],{timeout:8e3,maxBuffer:65536,env},(error62,stdout2)=>{if(error62?.killed)return resolve35({});try{let status2=JSON.parse(stdout2),loggedIn=status2&&typeof status2=="object"&&"loggedIn"in status2?status2.loggedIn:void 0;if(loggedIn!==!0)return resolve35(loggedIn===!1?{authenticated:!1}:{});let identity=status2,boundedText2=(value,max)=>typeof value=="string"&&value.trim().length>0&&value.
|
|
4065
4069
|
length<=max&&!/[\p{Cc}\p{Cf}]/u.test(value)?value.trim():void 0,candidateEmail=boundedText2(identity.email,254),email3=candidateEmail&&/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(candidateEmail)?candidateEmail:void 0,organization=boundedText2(identity.orgName,160),account2={...email3?{email:email3}:{},...organization?{organization}:{},...identity.authMethod==="api_key"?{method:"api-key"}:{}};resolve35({authenticated:!0,...Object.keys(account2).length?{account:account2}:{}})}catch{resolve35({})}})})}var init_claude_auth_status=__esm(
|
|
4066
|
-
{"server/drivers/claude-auth-status.ts"(){"use strict";init_procs()}});import{readFileSync as
|
|
4067
|
-
"server/drivers/claude-project-mcp.ts"(){"use strict"}});import{closeSync as closeSync12,constants as constants4,fstatSync as fstatSync5,openSync as openSync11,readFileSync as
|
|
4068
|
-
try{let real=realpathSync9(file2);if(real!==
|
|
4070
|
+
{"server/drivers/claude-auth-status.ts"(){"use strict";init_procs()}});import{readFileSync as readFileSync30}from"node:fs";import{join as join57}from"node:path";function projectMcpServers(cwd){let parsed;try{parsed=JSON.parse(readFileSync30(join57(cwd,".mcp.json"),"utf8"))}catch{return{}}let servers=parsed?.mcpServers;if(!servers||typeof servers!="object"||Array.isArray(servers))return{};let out={};for(let[name,server]of Object.entries(servers))server&&typeof server=="object"&&!Array.isArray(server)&&(out[name]=server);return out}var init_claude_project_mcp=__esm({
|
|
4071
|
+
"server/drivers/claude-project-mcp.ts"(){"use strict"}});import{closeSync as closeSync12,constants as constants4,fstatSync as fstatSync5,openSync as openSync11,readFileSync as readFileSync31,realpathSync as realpathSync9}from"node:fs";import{dirname as dirname26,join as join58}from"node:path";function entriesOf(value,keep){if(!isObject3(value))return;let entries2=Object.entries(value).map(([name,entry])=>[name,keep(entry,name)]).filter(([,entry])=>entry!==void 0);return entries2.length?Object.fromEntries(entries2):void 0}function readBotSettings(file2,cwd){
|
|
4072
|
+
try{let real=realpathSync9(file2);if(real!==join58(realpathSync9(dirname26(dirname26(file2))),".claude","settings.json"))return null;try{if(realpathSync9(join58(cwd,".claude","settings.json"))===real)return null}catch{}let fd=openSync11(real,constants4.O_RDONLY|(process.platform==="win32"?0:constants4.O_NOFOLLOW|constants4.O_NONBLOCK));try{let stat9=fstatSync5(fd);return stat9.isFile()&&stat9.size<=MAX_BYTES2?JSON.parse(readFileSync31(fd,"utf8")):null}finally{closeSync12(fd)}}catch{return null}}
|
|
4069
4073
|
function botSettingsFor(file2,cwd,processEnv){let parsed=file2?readBotSettings(file2,cwd):null;if(!isObject3(parsed))return{};let carried={hooks:entriesOf(parsed.hooks,matchers2=>Array.isArray(matchers2)?nonEmpty(matchers2.filter(isMatcher)):void 0),enabledPlugins:entriesOf(parsed.enabledPlugins,on2=>typeof on2=="boolean"||Array.isArray(on2)&&on2.every(item=>typeof item=="string")?on2:void 0),extraKnownMarketplaces:entriesOf(parsed.extraKnownMarketplaces,marketplace=>isObject3(marketplace)?marketplace:
|
|
4070
4074
|
void 0),permissions:entriesOf(parsed.permissions,(rules,key2)=>["allow","ask","deny","additionalDirectories"].includes(key2)&&Array.isArray(rules)?nonEmpty(rules.filter(rule=>typeof rule=="string")):void 0),env:entriesOf(parsed.env,(value,name)=>typeof value=="string"&&!Object.hasOwn(processEnv,name)?value:void 0)};return Object.fromEntries(Object.entries(carried).filter(([,value])=>value!==void 0))}function withBotSettings(bot,own4){return merged(bot,own4)}function merged(base2,over){return Array.
|
|
4071
4075
|
isArray(base2)&&Array.isArray(over)?[...base2,...over.filter(item=>!base2.includes(item))]:!isObject3(base2)||!isObject3(over)?over:Object.fromEntries([...new Set([...Object.keys(base2),...Object.keys(over)])].map(key2=>[key2,Object.hasOwn(over,key2)?Object.hasOwn(base2,key2)?merged(base2[key2],over[key2]):over[key2]:base2[key2]]))}var MAX_BYTES2,isObject3,isMatcher,nonEmpty,init_claude_bot_settings=__esm({"server/drivers/claude-bot-settings.ts"(){"use strict";MAX_BYTES2=1024*1024,isObject3=value=>typeof value==
|
|
@@ -4082,35 +4086,35 @@ function bedrockResultError(bedrock,environment,message5){return withBedrockCred
|
|
|
4082
4086
|
let extras=[...extrasFromUnknown(settings2.availableModels).map(extra=>({...extra,custom:!0})),...extrasFromUnknown(settings2.customModels).map(extra=>({...extra,custom:!0})),...extrasFromUnknown(settings2.extraModels).map(extra=>({...extra,custom:!official(extra.id)}))],nestedEnv=settings2.env&&typeof settings2.env=="object"?settings2.env:{},envModel=nestedEnv.ANTHROPIC_MODEL??env.ANTHROPIC_MODEL;typeof envModel=="string"&&extras.push(...extrasFromUnknown([envModel]).map(extra=>({...extra,custom:!0})));
|
|
4083
4087
|
let fromEnv=name=>{let value=nestedEnv[name]??env[name];return typeof value=="string"?value.trim():""},customOption=fromEnv("ANTHROPIC_CUSTOM_MODEL_OPTION");customOption&&extras.push(...extrasFromUnknown([{id:customOption,name:fromEnv("ANTHROPIC_CUSTOM_MODEL_OPTION_NAME")||void 0}]).map(extra=>({...extra,custom:!0})));for(let tier of["OPUS","SONNET","HAIKU"]){let model=fromEnv(`ANTHROPIC_DEFAULT_${tier}_MODEL`);model&&!official(model)&&extras.push(...extrasFromUnknown([model]).map(extra=>({...extra,
|
|
4084
4088
|
custom:!0})))}return{extras,envModel}}function endpointModelCatalog(models2){return models2?{default:models2[0],options:models2.map(id=>({id,label:id,custom:!0}))}:null}var OFFICIAL_CLAUDE_ID,official,STATIC_CLAUDE_MODELS,init_claude_model_extras=__esm({"server/drivers/claude-model-extras.ts"(){"use strict";init_bundled();init_schema2();init_manifest();OFFICIAL_CLAUDE_ID=/^claude-[a-z0-9.-]+$/,official=id=>OFFICIAL_CLAUDE_ID.test(id.replace(/\[1m\]$/i,""));STATIC_CLAUDE_MODELS=bundledEngineCatalog(
|
|
4085
|
-
"claude")}});import{readFileSync as
|
|
4089
|
+
"claude")}});import{readFileSync as readFileSync32,statSync as statSync17}from"node:fs";import{homedir as homedir16}from"node:os";import{basename as basename14,dirname as dirname27,join as join59,resolve as resolve20}from"node:path";function smallFile(path3){try{let stat9=statSync17(path3);return stat9.isFile()&&stat9.size<=FILE_MAX_BYTES2?readFileSync32(path3,"utf8"):null}catch{return null}}function claudeInteger(text13){let value=text13.trim();if(value.length<=32&&/^[+-]?(\d+(\.\d*)?|\.\d+)[eE][+-]?\d+$/.test(
|
|
4086
4090
|
value)){let number5=Number(value);return Number.isInteger(number5)?number5:Number.NaN}return value.length<=32&&/^[+-]?\d{1,3}([_, ])\d{3}(?:\1\d{3})*$/.test(value)?Number.parseInt(value.replace(/[_, ]/g,""),10):Number.parseInt(value,10)}function claudeToolSearchValue(value){if(!value||value==="auto")return"true";if(!value.startsWith("auto:"))return value;let percent=claudeInteger(value.slice(5));return Number.isNaN(percent)||percent>0&&percent<100?"true":value}function settingsValue(file2){
|
|
4087
|
-
let text13=smallFile(file2);if(text13!==null)try{let value=JSON.parse(text13)?.env?.ENABLE_TOOL_SEARCH;return typeof value=="string"?value:void 0}catch{return}}function checkoutRoot(folder){let git=
|
|
4088
|
-
let common=resolve20(worktree,commonDir);return basename14(common)===".git"?dirname27(common):folder}function localSettingsFolder(cwd,home2){if(process.platform==="win32")return cwd;for(let folder=cwd;;folder=dirname27(folder)){let root=checkoutRoot(folder);if(root!==null)return root===home2?cwd:root;if(dirname27(folder)===folder)return cwd}}function claudeToolSearchSetting(cwd,env){let home2=env.HOME||env.USERPROFILE||
|
|
4089
|
-
"settings.local.json"),...local===cwd?[]:[
|
|
4091
|
+
let text13=smallFile(file2);if(text13!==null)try{let value=JSON.parse(text13)?.env?.ENABLE_TOOL_SEARCH;return typeof value=="string"?value:void 0}catch{return}}function checkoutRoot(folder){let git=join59(folder,".git");try{if(!statSync17(git).isFile())return folder}catch{return null}let gitDir=/^gitdir:\s*(.+)$/m.exec(smallFile(git)??"")?.[1]?.trim();if(!gitDir)return folder;let worktree=resolve20(folder,gitDir),commonDir=smallFile(join59(worktree,"commondir"))?.trim();if(!commonDir)return folder;
|
|
4092
|
+
let common=resolve20(worktree,commonDir);return basename14(common)===".git"?dirname27(common):folder}function localSettingsFolder(cwd,home2){if(process.platform==="win32")return cwd;for(let folder=cwd;;folder=dirname27(folder)){let root=checkoutRoot(folder);if(root!==null)return root===home2?cwd:root;if(dirname27(folder)===folder)return cwd}}function claudeToolSearchSetting(cwd,env){let home2=env.HOME||env.USERPROFILE||homedir16(),local=localSettingsFolder(cwd,home2),files=[join59(local,".claude",
|
|
4093
|
+
"settings.local.json"),...local===cwd?[]:[join59(cwd,".claude","settings.local.json")],join59(cwd,".claude","settings.json"),join59(env.CLAUDE_CONFIG_DIR||join59(home2,".claude"),"settings.json")];for(let file2 of files){let value=settingsValue(file2);if(value!==void 0)return claudeToolSearchValue(value)}return claudeToolSearchValue(env.ENABLE_TOOL_SEARCH)}var FILE_MAX_BYTES2,init_claude_tool_search=__esm({"server/drivers/claude-tool-search.ts"(){"use strict";FILE_MAX_BYTES2=1024*1024}});function isSkillName(name){return name.length>=1&&name.length<=64&&SKILL_NAME.test(name)}function parseSkillTags(raw){if(!raw)return;let tags=[...new Set(raw.split(",").map(tag2=>tag2.trim().toLowerCase()).filter(tag2=>TAG_PATTERN.test(tag2)))].slice(0,SKILL_TAGS_MAX);return tags.length>0?tags:void 0}function unquoteScalar(raw){let value=raw.trim();if(value.length>=2){let last=value.length-1;if(value[0]==='"'&&value[last]==='"'){let out="";for(let i2=1;i2<last;i2+=1){let c2=value[i2];if(c2==="\\"&&
|
|
4090
4094
|
i2+1<last){let next=value[i2+1];if(next==='"'||next==="\\"||next==="n"){out+=next==="n"?`
|
|
4091
4095
|
`:next,i2+=1;continue}}out+=c2}return out}if(value[0]==="'"&&value[last]==="'")return value.slice(1,-1).replace(/''/g,"'")}return value}function parseSkillMd(raw){let frontmatter=readSkillFrontmatter(raw);if(!frontmatter)return{error:"SKILL.md has no YAML frontmatter (--- block) at the top"};let{fields:fields2}=frontmatter,name=fields2.name??"",description=fields2.description??"";return isSkillName(name)?!description||description.length>1024?{error:"frontmatter description is required and must b\
|
|
4092
4096
|
e at most 1024 characters"}:{name,description,license:fields2.license||void 0,compatibility:fields2.compatibility||void 0,tags:parseSkillTags(fields2.tags),body:frontmatter.body}:{error:`frontmatter name ${JSON.stringify(name)} is not a valid skill name (lowercase, hyphens, max 64)`}}function readSkillFrontmatter(raw){raw.charCodeAt(0)===65279&&(raw=raw.slice(1));let match=raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);if(!match)return null;let fields2={};for(let line3 of match[1].split(
|
|
4093
|
-
/\r?\n/)){let kv=line3.match(/^([A-Za-z][\w-]*):\s*(.*)$/);kv&&(fields2[kv[1].toLowerCase()]=unquoteScalar(kv[2]))}return{fields:fields2,body:match[2]??""}}var SKILL_NAME,TAG_PATTERN,SKILL_TAGS_MAX,init_skill_md=__esm({"shared/skill-md.ts"(){"use strict";SKILL_NAME=/^[a-z0-9]+(?:-[a-z0-9]+)*$/;TAG_PATTERN=/^[a-z0-9][a-z0-9-]{0,23}$/,SKILL_TAGS_MAX=8}});import{mkdirSync as
|
|
4094
|
-
e-skill-choices.ts"(){"use strict";init_zod();init_atomic();init_config3();init_skill_md();choicesPath=botId=>
|
|
4097
|
+
/\r?\n/)){let kv=line3.match(/^([A-Za-z][\w-]*):\s*(.*)$/);kv&&(fields2[kv[1].toLowerCase()]=unquoteScalar(kv[2]))}return{fields:fields2,body:match[2]??""}}var SKILL_NAME,TAG_PATTERN,SKILL_TAGS_MAX,init_skill_md=__esm({"shared/skill-md.ts"(){"use strict";SKILL_NAME=/^[a-z0-9]+(?:-[a-z0-9]+)*$/;TAG_PATTERN=/^[a-z0-9][a-z0-9-]{0,23}$/,SKILL_TAGS_MAX=8}});import{mkdirSync as mkdirSync25,readFileSync as readFileSync33}from"node:fs";import{dirname as dirname28,join as join60}from"node:path";function readChoices(botId){try{let parsed=choicesSchema.safeParse(JSON.parse(readFileSync33(choicesPath(botId),"utf8")));if(parsed.success)return{off:parsed.data.off.filter(isSkillName).sort()}}catch{}return{off:[]}}function disabledNativeSkillNames(botId){return readChoices(botId).off}var choicesPath,choicesSchema,init_native_skill_choices=__esm({"server/nativ\
|
|
4098
|
+
e-skill-choices.ts"(){"use strict";init_zod();init_atomic();init_config3();init_skill_md();choicesPath=botId=>join60(DATA_DIR,"skill-state",botId,"native-skills.json"),choicesSchema=external_exports.object({off:external_exports.array(external_exports.string())})}});function unusableBuiltIns(turn){return turn.isolated&&!turn.listsTools&&!turn.guest?BUILT_INS_NO_BOT_CAN_USE:[]}function claudeDisabledNativeSkillRules(botId){return botId?disabledNativeSkillNames(botId).map(name=>`Skill(${name})`):[]}var BUILT_INS_NO_BOT_CAN_USE,init_claude_unusable_tools=__esm({"server/drivers/claude-unusable-tools.ts"(){"use strict";init_native_skill_choices();BUILT_INS_NO_BOT_CAN_USE=["Workflow","ScheduleWakeup","ReportFindings","ListAgents"]}});function claudeElicitations(write,emit){let pending=new Set,sending=new Map,reply=(id,response)=>write({type:"control_response",response:{subtype:"success",request_id:id,response}}),resolved2=(id,behavior,source)=>emit({type:"request.resolved",requestId:CARD_PREFIX+id,behavior,source});return{frame(o){if(o?.type==="control_cancel_request")return typeof o.request_id!="string"?!1:sending.has(o.request_id)?(sending.get(o.request_id)||resolved2(o.request_id,"deny","timeout"),sending.set(o.request_id,
|
|
4095
4099
|
!0),!0):pending.delete(o.request_id)?(resolved2(o.request_id,"deny","timeout"),!0):!1;if(o?.type!=="control_request"||o.request?.subtype!=="elicitation"||typeof o.request_id!="string")return!1;let id=o.request_id,r2=o.request,serverName=text8(r2.mcp_server_name),server=text8(r2.display_name)||serverName,message5=text8(r2.message),properties=r2.requested_schema?.properties,required3=r2.requested_schema?.required,fields2=new Set([...properties&&typeof properties=="object"?Object.keys(properties):[],
|
|
4096
4100
|
...Array.isArray(required3)?required3.filter(name=>typeof name=="string"):[]]).size;if(r2.mode==="url"||fields2>0){reply(id,{action:"decline"});let url3=text8(r2.url),withUrl=/^https:\/\//i.test(url3),key2=r2.mode==="url"?`chat.notice.elicitationUrlDeclined${server?"":"Generic"}${withUrl?"WithUrl":""}`:`chat.notice.elicitationFormDeclined${server?"":"Generic"}${fields2===1?"One":"Many"}${message5?"Message":""}`;return emit({type:"runtime.notice",...noticeFailure(key2,{...server?{server}:{},...r2.
|
|
4097
4101
|
mode==="url"?withUrl?{url:url3}:{}:{...fields2===1?{}:{fields:fields2},...message5?{message:message5}:{}}})}),!0}pending.add(id);let summary2=message5?server?{summary:`${server}: ${message5}`}:noticeSummary("chat.notice.elicitationMessageGeneric",{message:message5}):server?noticeSummary("chat.notice.elicitationContinue",{server}):noticeSummary("chat.notice.elicitationContinueGeneric");return emit({type:"request.opened",requestId:CARD_PREFIX+id,requestType:"permission",tool:serverName?`mcp__${serverName}`:
|
|
4098
4102
|
"mcp",...summary2,requiresExplicitApproval:!0}),!0},async answer(requestId,behavior){let id=requestId.startsWith(CARD_PREFIX)?requestId.slice(CARD_PREFIX.length):"";if(!pending.delete(id))return!1;sending.set(id,!1);let delivered=await reply(id,behavior==="allow"?{action:"accept",content:{}}:{action:"decline"}),cancelled=sending.get(id);return sending.delete(id),cancelled?"failed":delivered?(resolved2(id,behavior==="allow"?"allow":"deny","user"),"sent"):(resolved2(id,"deny","system"),"failed")},
|
|
4099
|
-
close(){for(let id of pending)resolved2(id,"deny","system");pending.clear();for(let[id,withdrawn]of sending)withdrawn||(resolved2(id,"deny","system"),sending.set(id,!0))}}}var CARD_PREFIX,text8,init_claude_elicitation=__esm({"server/drivers/claude-elicitation.ts"(){"use strict";init_chat_notices();CARD_PREFIX="elicitation:",text8=value=>typeof value=="string"?value.trim():""}});import{readFileSync as
|
|
4103
|
+
close(){for(let id of pending)resolved2(id,"deny","system");pending.clear();for(let[id,withdrawn]of sending)withdrawn||(resolved2(id,"deny","system"),sending.set(id,!0))}}}var CARD_PREFIX,text8,init_claude_elicitation=__esm({"server/drivers/claude-elicitation.ts"(){"use strict";init_chat_notices();CARD_PREFIX="elicitation:",text8=value=>typeof value=="string"?value.trim():""}});import{readFileSync as readFileSync34}from"node:fs";import{join as join61}from"node:path";function isCostSnapshot(value){if(!value||typeof value!="object")return!1;let{total,models:models2}=value;return typeof total=="number"&&!!models2&&typeof models2=="object"&&Object.values(models2).every(counts=>Array.isArray(counts)&&counts.length===4&&counts.every(n3=>typeof n3=="number"))}function readCostHistory(){try{let parsed=JSON.parse(readFileSync34(COST_HISTORY_FILE,"utf8"));return!parsed||typeof parsed!=
|
|
4100
4104
|
"object"||Array.isArray(parsed)?{}:Object.fromEntries(Object.entries(parsed).map(([id,states2])=>[id,Array.isArray(states2)?states2.filter(isCostSnapshot):[]]))}catch{return{}}}function recordCostState(sessionId,state){let history=readCostHistory(),states2=[...history[sessionId]??[],state].slice(-COST_HISTORY_STATES);delete history[sessionId],history[sessionId]=states2;let ids=Object.keys(history);for(let id of ids.slice(0,Math.max(0,ids.length-COST_HISTORY_SESSIONS)))delete history[id];try{writeFileAtomic(
|
|
4101
|
-
COST_HISTORY_FILE,JSON.stringify(history),{mode:384,durable:!1})}catch{}}var COST_HISTORY_FILE,COST_HISTORY_SESSIONS,COST_HISTORY_STATES,init_claude_cost_history=__esm({"server/drivers/claude-cost-history.ts"(){"use strict";init_config3();init_atomic();COST_HISTORY_FILE=
|
|
4105
|
+
COST_HISTORY_FILE,JSON.stringify(history),{mode:384,durable:!1})}catch{}}var COST_HISTORY_FILE,COST_HISTORY_SESSIONS,COST_HISTORY_STATES,init_claude_cost_history=__esm({"server/drivers/claude-cost-history.ts"(){"use strict";init_config3();init_atomic();COST_HISTORY_FILE=join61(DATA_DIR,"claude-cost-history.json"),COST_HISTORY_SESSIONS=100,COST_HISTORY_STATES=8}});import{randomUUID as randomUUID12}from"node:crypto";import{homedir as homedir17}from"node:os";import{isAbsolute as isAbsolute13,join as join62,resolve as resolve21}from"node:path";import{stripVTControlCharacters as stripVTControlCharacters6}from"node:util";function claudeSignInLink(value){if(!value)return null;try{let url3=new URL(value),host2=url3.hostname.toLowerCase(),trusted=SIGN_IN_HOSTS.some(allowed2=>host2===allowed2||host2.endsWith(`.${allowed2}`));return url3.protocol==="https:"&&trusted&&
|
|
4102
4106
|
!url3.username&&!url3.password?url3.href:null}catch{return null}}function claudeLoginPrompt(output2){let lines2=stripVTControlCharacters6(output2).split(/\r?\n/).slice(0,-1);for(let line3 of lines2){let match=/(https:\/\/\S+)/.exec(line3.trim()),link2=match?claudeSignInLink(match[1].replace(/[),.;]+$/,"")):null;if(link2)return{authorizationUrl:link2}}return null}function claudeLoginCode(value){let code=value.trim();return/^[A-Za-z0-9_\-#.:]{8,1024}$/.test(code)?code:null}var MAX_OUTPUT3,SIGN_IN_HOSTS,
|
|
4103
4107
|
authenticatingHomes2,NOT_AVAILABLE,ClaudeLoginController,init_claude_login_auth=__esm({"server/drivers/claude-login-auth.ts"(){"use strict";init_procs();init_device_auth();MAX_OUTPUT3=32768,SIGN_IN_HOSTS=["claude.com","claude.ai","console.anthropic.com","platform.claude.com"],authenticatingHomes2=new Set;NOT_AVAILABLE="This sign-in is no longer available. Start sign-in again.",ClaudeLoginController=class{flow=null;logoutChild=null;signingOut=null;disposed=!1;options;constructor(options2){this.options=
|
|
4104
4108
|
options2}async start(){if(this.disposed)throw new Error("This provider was removed. Refresh Settings before signing in.");if(this.flow?.status.phase==="waiting"){if(this.flow.ready)return{...this.flow.status,phase:"waiting"};throw new Error("A Claude sign-in is already starting. Please wait for the link.")}if(await this.flow?.stopping,this.disposed)throw new Error("This provider was removed. Refresh Settings before signing in.");let env=this.options.environment(),home2=env.HOME||env.USERPROFILE||
|
|
4105
|
-
|
|
4109
|
+
homedir17();if(!isAbsolute13(home2)||env.CLAUDE_CONFIG_DIR&&!isAbsolute13(env.CLAUDE_CONFIG_DIR))throw new Error("Use an absolute HOME and CLAUDE_CONFIG_DIR path for this server's Claude provider before signing in.");let homeKey=canonicalPath(resolve21(env.CLAUDE_CONFIG_DIR||join62(home2,".claude")));if(authenticatingHomes2.has(homeKey))throw new Error("A Claude sign-in is already running for this server account. Finish or cancel it before starting another.");return authenticatingHomes2.add(homeKey),
|
|
4106
4110
|
new Promise((resolveStart,reject)=>{let flow3={status:{phase:"waiting",flowId:randomUUID12(),authorizationUrl:null,expiresAt:new Date(Date.now()+(this.options.lifetimeMs??9e5)).toISOString()},child:null,ready:!1,codeSent:!1,output:"",resolve:resolveStart,reject,homeKey,env,startupTimer:setTimeout(()=>this.finish(flow3,"failed","Claude Code did not show a sign-in link in time. Check that it is installed and up to date on the server, then try again."),this.options.startupTimeoutMs??3e4),expiryTimer:setTimeout(
|
|
4107
4111
|
()=>this.finish(flow3,"expired","The Claude sign-in link expired. Start sign-in again."),this.options.lifetimeMs??9e5)};flow3.startupTimer.unref(),flow3.expiryTimer.unref(),this.flow=flow3,this.signedIn(env).then(already=>{if(flow3.status.phase==="waiting"){if(already){this.finish(flow3,"succeeded");return}this.login(flow3)}})})}async complete(flowId,pasted){let flow3=this.flow;if(!flowId||flow3?.status.flowId!==flowId)throw new Error(NOT_AVAILABLE);if(flow3.status.phase!=="waiting"||!flow3.ready)
|
|
4108
4112
|
throw new Error(NOT_AVAILABLE);if(flow3.codeSent)throw new Error("A code was already sent for this sign-in. Wait for the result, or cancel and start again.");let code=claudeLoginCode(pasted);if(!code)throw new Error("Paste the whole code shown on Anthropic's page after signing in.");let child=flow3.child,stdin2=child?.stdin;if(!child||!stdin2||child.exitCode!==null||child.signalCode!==null)throw new Error(NOT_AVAILABLE);flow3.codeSent=!0,await new Promise((resolveDone,rejectDone)=>{flow3.completion=
|
|
4109
4113
|
{resolve:resolveDone,reject:rejectDone},setTimeout(()=>this.finish(flow3,"failed","Claude Code did not finish the sign-in after the code was entered. Start sign-in again."),this.options.completeTimeoutMs??6e4).unref(),stdin2.write(`${code}
|
|
4110
4114
|
`,error62=>{error62&&this.finish(flow3,"failed","The code could not be handed to Claude Code on the server. Start sign-in again.")})})}async get(flowId){if(!flowId||this.flow?.status.flowId!==flowId)throw new Error(NOT_AVAILABLE);return{...this.flow.status}}async cancel(){if(this.flow?.status.phase==="waiting"&&this.finish(this.flow,"cancelled","Claude sign-in cancelled."),await this.flow?.stopping,this.flow?.terminationFailed)throw new Error(this.flow.status.message);if(this.logoutChild&&!await this.
|
|
4111
4115
|
stopChild(this.logoutChild))throw new Error("Claude Code could not be stopped on this server. Ask the server administrator to stop the account command before trying again.")}async dispose(){this.disposed=!0,await this.cancel();let signingOut=this.signingOut;signingOut&&await Promise.race([signingOut.catch(()=>{}),new Promise(resolve35=>setTimeout(resolve35,1500).unref())]),this.flow=null}async signOut(){let run6=this.signOutNow();this.signingOut=run6;try{await run6}finally{this.signingOut===run6&&
|
|
4112
|
-
(this.signingOut=null)}}async signOutNow(){if(this.disposed)throw new Error("This provider was removed. Refresh Settings before signing out.");if(this.flow?.status.phase==="waiting")throw new Error("Finish or cancel the Claude sign-in in progress before signing out.");if(await this.flow?.stopping,this.disposed)throw new Error("This provider was removed. Refresh Settings before signing out.");let env=this.options.environment(),home2=env.HOME||env.USERPROFILE||
|
|
4113
|
-
env.CLAUDE_CONFIG_DIR&&!isAbsolute13(env.CLAUDE_CONFIG_DIR))throw new Error("Use an absolute HOME and CLAUDE_CONFIG_DIR path for this server's Claude provider before signing out.");let homeKey=canonicalPath(resolve21(env.CLAUDE_CONFIG_DIR||
|
|
4116
|
+
(this.signingOut=null)}}async signOutNow(){if(this.disposed)throw new Error("This provider was removed. Refresh Settings before signing out.");if(this.flow?.status.phase==="waiting")throw new Error("Finish or cancel the Claude sign-in in progress before signing out.");if(await this.flow?.stopping,this.disposed)throw new Error("This provider was removed. Refresh Settings before signing out.");let env=this.options.environment(),home2=env.HOME||env.USERPROFILE||homedir17();if(!isAbsolute13(home2)||
|
|
4117
|
+
env.CLAUDE_CONFIG_DIR&&!isAbsolute13(env.CLAUDE_CONFIG_DIR))throw new Error("Use an absolute HOME and CLAUDE_CONFIG_DIR path for this server's Claude provider before signing out.");let homeKey=canonicalPath(resolve21(env.CLAUDE_CONFIG_DIR||join62(home2,".claude")));if(authenticatingHomes2.has(homeKey))throw new Error("A Claude sign-in is running for this server account. Finish or cancel it before signing out.");authenticatingHomes2.add(homeKey);try{if(await this.logout(env),this.disposed)throw new Error(
|
|
4114
4118
|
"This provider was removed. Refresh Settings before signing out.");let status2=await this.authStatus(env);if(status2==="in")throw new Error("Claude Code still reports a sign-in on this server. Update Claude Code and check its auth status before trying again.");if(status2==="unknown")throw new Error("Claude Code could not confirm the sign-out on this server. Update Claude Code and check its auth status before trying again.")}finally{let child=this.logoutChild;child&&child.exitCode===null&&child.signalCode===
|
|
4115
4119
|
null?child.once("close",()=>authenticatingHomes2.delete(homeKey)):authenticatingHomes2.delete(homeKey)}}logout(env){return new Promise((resolveDone,rejectDone)=>{if(this.disposed){rejectDone(new Error("This provider was removed. Refresh Settings before signing out."));return}let child;try{child=spawnCli(this.options.cli,["auth","logout"],{env:{...env,NO_COLOR:"1"},stdio:["pipe","pipe","pipe"]})}catch{rejectDone(new Error("Claude Code could not start on this server. Install or update the configur\
|
|
4116
4120
|
ed Claude CLI, then try again."));return}this.logoutChild=child,child.stdin.end(),child.stdout.on("data",()=>{}),child.stderr.on("data",()=>{});let timer2=setTimeout(()=>{this.stopChild(child).catch(()=>!1).then(stopped=>{stopped||rejectDone(new Error("Claude Code could not be stopped on this server. Ask the server administrator to stop the account command before trying again."))})},this.options.startupTimeoutMs??3e4);timer2.unref(),child.once("error",error62=>{clearTimeout(timer2),rejectDone(new Error(
|
|
@@ -4155,7 +4159,7 @@ sha256:external_exports.string().regex(/^[a-f0-9]{64}$/),importedAt:external_exp
|
|
|
4155
4159
|
string()),package:external_exports.object({installId:external_exports.string().regex(/^[a-f0-9]{32}$/),key:external_exports.string().min(1).max(64),release:external_exports.string().min(1).max(40),r:external_exports.string().regex(/^[a-f0-9]{64}$/),w:external_exports.string().regex(/^[a-f0-9]{64}$/),via:external_exports.literal("preset").optional()}).optional(),...skillFolderRecordSchema,github:githubSkillOriginSchema.optional(),descriptionHistory:external_exports.array(external_exports.object({
|
|
4156
4160
|
description:external_exports.string(),until:external_exports.number()})).optional()}),skillLibraryIndexSchema=external_exports.record(external_exports.string(),skillLibraryEntrySchema),skillLibraryEvents=new EventEmitter,libraryOptOutSchema=external_exports.array(external_exports.string())}});var managedLinksSchema,init_skill_link_registry=__esm({"server/skill-link-registry.ts"(){"use strict";init_zod();init_atomic();init_config3();init_skill_md();managedLinksSchema=external_exports.array(external_exports.string())}});var init_memory_entries=__esm({"server/memory-entries.ts"(){"use strict"}});var CJK,CJK_CHAR,HAN,CJK_RUNS,CJK_BOUNDARY,FILLER,init_cjk_search=__esm({"server/cjk-search.ts"(){"use strict";CJK="\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}",CJK_CHAR=new RegExp(`[${CJK}]`,"u"),HAN=new RegExp("\\p{Script=Han}","u"),CJK_RUNS=new RegExp(`[${CJK}]+|[^${CJK}]+`,"gu"),CJK_BOUNDARY=new RegExp(`(?<=[${CJK}])(?=[\\p{L}\\p{N}])|(?<=[\\p{L}\\p{N}])(?=[${CJK}])`,"gu"),FILLER=new RegExp("\u6211\u4EEC|\u4F60\u4EEC|\u4ED6\u4EEC|\u5979\u4EEC|\u5B83\u4EEC|\u8FD9\u4E2A|\u90A3\u4E2A|\u4E00\u4E0B|\u4E00\u4E2A|\u53EF\u4EE5|\u65F6\u5019|\u73B0\u5728|\u77E5\u9053|\u544A\u8BC9|\u8BB0\u5F97|\u8FD8\u662F|\u5C31\u662F|\u4E0D\u662F|\u6CA1\u6709|\u5DF2\u7ECF|\u56E0\u4E3A|\u6240\u4EE5|\u4F46\u662F|\u5982\u679C|\u7136\u540E|\u8FD8\u6709|\u8BF7\u95EE|\u5E2E\u6211|\u600E\u6837|\u8FD9\u6837\
|
|
4157
4161
|
|\u90A3\u6837|\u54EA\u91CC|\u54EA\u4E2A|\u5E94\u8BE5|\u4E00\u4E9B|[\u7684\u4E86\u662F\u5417\u5462\u5427\u554A\u5440\u54E6\u55EF\u4E48]","gu")}});var init_memory_topics=__esm({"server/memory-topics.ts"(){"use strict";init_cjk_search()}});var init_message_db_memory_index=__esm({"server/message-db-memory-index.ts"(){"use strict";init_cjk_search()}});var init_message_db_attention=__esm({"server/message-db-attention.ts"(){"use strict"}});var init_message_search_worker=__esm({"server/message-search-worker.ts"(){"use strict"}});var init_message_search_query=__esm({"server/message-search-query.ts"(){"use strict"}});import{DatabaseSync as DatabaseSync3}from"node:sqlite";var closingSearch,STOP_WORDS2,RECALL_FILLER,init_message_db=__esm({"server/message-db.ts"(){"use strict";init_config3();init_peer_provenance();init_message_db_memory_index();init_cjk_search();init_message_db_attention();init_message_search_worker();init_message_search_query();closingSearch=Promise.resolve(),STOP_WORDS2=new Set("a an and are as at be by did do for from had has have how i in is it its of on or that the this to was we were what\
|
|
4158
|
-
when where which who why with you your".split(" ")),RECALL_FILLER=new Set("about again also any anything can could does don't know me my please remember remind should tell there they us would hi hello hey thanks thank ok okay yes yeah no i'm im i've i'll i'd you're quick just".split(" "))}});import{join as
|
|
4162
|
+
when where which who why with you your".split(" ")),RECALL_FILLER=new Set("about again also any anything can could does don't know me my please remember remind should tell there they us would hi hello hey thanks thank ok okay yes yeah no i'm im i've i'll i'd you're quick just".split(" "))}});import{join as join63}from"node:path";var WORKSPACES_DIR,TASK_WORKSPACES_DIR,MEMORY_MAX_LINES,MEMORY_SEEDS,MEMORY_SEED_VALUES,MEMORY_FILE_MAX_BYTES,init_workspace=__esm({"server/workspace.ts"(){"use strict";init_atomic();init_memory_entries();init_memory_topics();init_message_db();init_redact2();init_config3();WORKSPACES_DIR=join63(DATA_DIR,"workspaces"),TASK_WORKSPACES_DIR=join63(DATA_DIR,"task-workspaces"),MEMORY_MAX_LINES=200,MEMORY_SEEDS={en:`# Memory
|
|
4159
4163
|
|
|
4160
4164
|
Durable notes this bot keeps between tasks. The first ${MEMORY_MAX_LINES} lines
|
|
4161
4165
|
load at the start of every session \u2014 keep this file short and curated.
|
|
@@ -4185,7 +4189,7 @@ string(),sha256:external_exports.string().regex(/^[a-f0-9]{64}$/),importedAt:ext
|
|
|
4185
4189
|
string().optional(),storageRevision:external_exports.string().regex(/^[a-f0-9]{64}$/).optional(),package:external_exports.object({installId:external_exports.string().regex(/^[a-f0-9]{32}$/),key:external_exports.string().min(1).max(64),release:external_exports.string().min(1).max(40),r:external_exports.string().regex(/^[a-f0-9]{64}$/),w:external_exports.string().regex(/^[a-f0-9]{64}$/),via:external_exports.literal("preset").optional()}).optional()}),skillManifestSchema=external_exports.record(external_exports.
|
|
4186
4190
|
string(),skillManifestEntrySchema),stagedSkillWriteSchema=external_exports.object({id:external_exports.string(),action:external_exports.enum(["create","update"]),name:external_exports.string().refine(isSkillName),gist:external_exports.string(),source:external_exports.string(),files:external_exports.array(external_exports.object({path:external_exports.string(),content:external_exports.string()})),sha256:external_exports.string().regex(/^[a-f0-9]{64}$/),referencesSha256:external_exports.string().regex(
|
|
4187
4191
|
/^[a-f0-9]{64}$/).optional(),warnings:external_exports.array(external_exports.string()),skippedFiles:external_exports.array(external_exports.string()),createdAt:external_exports.string(),baseSha256:external_exports.string().regex(/^[a-f0-9]{64}$/).optional(),baseAppliedStageId:external_exports.string().optional()}).superRefine((entry,ctx)=>{entry.action==="update"&&(!entry.baseSha256||!entry.baseAppliedStageId)&&ctx.addIssue({code:"custom",message:"updated skills require their reviewed base revi\
|
|
4188
|
-
sion"})}),stagedStoreSchema=external_exports.object({writes:external_exports.record(external_exports.string(),stagedSkillWriteSchema)})}});import{dirname as dirname29,isAbsolute as isAbsolute14,join as
|
|
4192
|
+
sion"})}),stagedStoreSchema=external_exports.object({writes:external_exports.record(external_exports.string(),stagedSkillWriteSchema)})}});import{dirname as dirname29,isAbsolute as isAbsolute14,join as join64,resolve as resolve22}from"node:path";var IMPORTED_SKILLS_DIR,INDEX_PATH,sha256Hex,entrySchema,indexSchema,choicesSchema2,init_imported_skills=__esm({"server/imported-skills.ts"(){"use strict";init_zod();init_skill_fit();init_skill_md();init_atomic();init_config3();init_skill_storage();init_skills();IMPORTED_SKILLS_DIR=join64(DATA_DIR,"imported-skills"),INDEX_PATH=join64(DATA_DIR,"skill-state","imported-skills.json"),sha256Hex=
|
|
4189
4193
|
external_exports.string().regex(/^[a-f0-9]{64}$/),entrySchema=external_exports.object({description:external_exports.string(),source:external_exports.enum(["claudeCode","codex"]),root:external_exports.string(),origin:external_exports.string(),label:external_exports.string(),sha256:sha256Hex,filesSha256:sha256Hex,importedAt:external_exports.string(),warnings:external_exports.array(external_exports.string()),license:external_exports.string().optional(),compatibility:external_exports.string().optional()}),
|
|
4190
4194
|
indexSchema=external_exports.record(external_exports.string(),entrySchema),choicesSchema2=external_exports.object({off:external_exports.array(external_exports.string()),on:external_exports.record(external_exports.string(),sha256Hex).default({}),listed:external_exports.array(external_exports.string()).optional()})}});function parseToml(source){let text13=source.charCodeAt(0)===65279?source.slice(1):source,i2=0,root=table(),current=root,fail3=message5=>{throw new TomlError(`line ${text13.slice(0,i2).split(`
|
|
4191
4195
|
`).length}: ${message5}`)},spaces=()=>{for(;text13[i2]===" "||text13[i2]===" ";)i2++},comment=()=>{if(text13[i2]==="#")for(;i2<text13.length&&text13[i2]!==`
|
|
@@ -4207,21 +4211,21 @@ at2=next}else Array.isArray(existing)&&isTable(existing[existing.length-1])?at2=
|
|
|
4207
4211
|
rver/toml-lite.ts"(){"use strict";TomlError=class extends Error{},table=()=>Object.create(null),isTable=value=>typeof value=="object"&&value!==null&&!Array.isArray(value),BARE_KEY=/[A-Za-z0-9_-]/,VALUE_END=/[\s,\]}#]/,MAX_DEPTH2=64,MAX_KEY_PARTS=16}});function skipString(text13,start){for(let at2=start+1;;){let quote=text13.indexOf('"',at2);if(quote<0)return-1;let slashes=0;for(;text13[quote-1-slashes]==="\\";)slashes++;if(slashes%2===0)return quote+1;at2=quote+1}}function skipValue(text13,start){if(text13[start]==='"')return skipString(text13,start);if(text13[start]!=="{"&&text13[start]!=="["){let at2=start;for(;at2<text13.length&&!/[\s,}\]]/.test(text13[at2]);)at2++;return at2>start?at2:-1}let depth=0;for(let at2=start;at2<text13.length;){let char=text13[at2];
|
|
4208
4212
|
if(char==='"'){if(at2=skipString(text13,at2),at2<0)return-1;continue}if(char==="{"||char==="[")depth++;else if((char==="}"||char==="]")&&(depth--,depth===0))return at2+1;at2++}return-1}function topLevelJsonMember(text13,name){let spaces=at3=>{for(;at3<text13.length&&/\s/.test(text13[at3]);)at3++;return at3},at2=spaces(text13.charCodeAt(0)===65279?1:0);if(text13[at2]!=="{")return null;let found=null;if(at2=spaces(at2+1),text13[at2]==="}")return null;for(;;){if(text13[at2]!=='"')return null;let keyEnd=skipString(
|
|
4209
4213
|
text13,at2);if(keyEnd<0)return null;let key2;try{key2=JSON.parse(text13.slice(at2,keyEnd))}catch{return null}if(at2=spaces(keyEnd),text13[at2]!==":")return null;at2=spaces(at2+1);let valueEnd=skipValue(text13,at2);if(valueEnd<0)return null;if(key2===name&&(found=text13.slice(at2,valueEnd)),at2=spaces(valueEnd),text13[at2]===","){at2=spaces(at2+1);continue}if(text13[at2]!=="}"||found===null)return null;try{return JSON.parse(found)}catch{return null}}}var CONFIG_MAX_BYTES,CLAUDE_JSON_MAX_BYTES,SKILL_COPY_LIMITS,
|
|
4210
|
-
decoder2,init_setup_import=__esm({"server/setup-import.ts"(){"use strict";init_redact();init_skill_md();init_imported_skills();init_skill_folder();init_mcp_registry();init_toml_lite();CONFIG_MAX_BYTES=1024*1024,CLAUDE_JSON_MAX_BYTES=256*1024*1024,SKILL_COPY_LIMITS={fileBytes:512*1024,skillBytes:4*1024*1024,skillFiles:200,totalBytes:48*1024*1024,depth:6},decoder2=new TextDecoder("utf-8",{fatal:!0})}});import{readFile as readFile5,stat as stat8}from"node:fs/promises";import{join as
|
|
4211
|
-
function claudeAccountFiles(env){let home2=userHome(env),folder=env.CLAUDE_CONFIG_DIR?.trim();return[
|
|
4214
|
+
decoder2,init_setup_import=__esm({"server/setup-import.ts"(){"use strict";init_redact();init_skill_md();init_imported_skills();init_skill_folder();init_mcp_registry();init_toml_lite();CONFIG_MAX_BYTES=1024*1024,CLAUDE_JSON_MAX_BYTES=256*1024*1024,SKILL_COPY_LIMITS={fileBytes:512*1024,skillBytes:4*1024*1024,skillFiles:200,totalBytes:48*1024*1024,depth:6},decoder2=new TextDecoder("utf-8",{fatal:!0})}});import{readFile as readFile5,stat as stat8}from"node:fs/promises";import{join as join65}from"node:path";function claudeModelKey(id){return id.trim().toLowerCase().replace(/(?:\[1m\])+$/,"").replace(/-\d{8}$/,"")}function parseOrgBlockedModels(text13){let blocked=new Set,cache2=topLevelJsonMember(text13,"modelAccessCache");if(!Array.isArray(cache2))return blocked;for(let entry of cache2)typeof entry?.apiName=="string"&&entry.entitled===!1&&blocked.add(claudeModelKey(entry.apiName));return blocked}
|
|
4215
|
+
function claudeAccountFiles(env){let home2=userHome(env),folder=env.CLAUDE_CONFIG_DIR?.trim();return[join65(folder||join65(home2,".claude"),".config.json"),join65(folder||home2,".claude.json")]}function withOrgBlocks(catalog,blocked){let options2=catalog.options.map(({orgBlocked:_stale,...option})=>!option.custom&&blocked.has(claudeModelKey(option.id))?{...option,orgBlocked:!0}:option),usable=id=>options2.some(option=>option.id===id&&!option.orgBlocked&&!option.needsCliUpdate),fallback=options2.
|
|
4212
4216
|
find(option=>!option.orgBlocked&&!option.needsCliUpdate&&!option.custom)?.id;return{...catalog,default:usable(catalog.default)?catalog.default:fallback??catalog.default,options:options2}}function createOrgModelBlocks(environments,apply,read2=path3=>readFile5(path3,"utf8")){let lastRead="";return{async refresh(force=!1){let newest=null;for(let env of environments()){if(CLOUD_BACKEND_ENV.some(key2=>env[key2]))return apply(new Set);for(let path3 of claudeAccountFiles(env)){let found=await stat8(path3).
|
|
4213
4217
|
catch(()=>null);if(!(!found?.isFile()||found.size===0)){(!newest||found.mtimeMs>newest.mtimeMs)&&(newest={path:path3,mtimeMs:found.mtimeMs,size:found.size});break}}}let version2=newest?`${newest.path}:${newest.mtimeMs}`:"none";if(!force&&version2===lastRead)return;if(!newest||newest.size>ACCOUNT_FILE_MAX_BYTES)return lastRead=version2,apply(new Set);let text13=await read2(newest.path).catch(()=>null);text13!==null&&(lastRead=version2,apply(parseOrgBlockedModels(text13)))}}}function otherModelAnswered(picked,answered2){
|
|
4214
4218
|
if(!picked||typeof answered2!="string")return!1;let[asked,got]=[claudeModelKey(picked),claudeModelKey(answered2)];return OFFICIAL_MODEL.test(asked)&&OFFICIAL_MODEL.test(got)&&asked!==got}function modelSwapNotice(session,threadId,picked,frame,catalog){let answered2=frame.message?.model;if(frame.parent_tool_use_id||!otherModelAnswered(picked,answered2))return null;let said=told.get(session)??new Set;told.set(session,said);let pair=`${claudeModelKey(picked)} ${claudeModelKey(answered2)}`;if(said.has(
|
|
4215
4219
|
pair))return null;said.add(pair);let option=id=>catalog.options.find(candidate=>claudeModelKey(candidate.id)===claudeModelKey(id)),names={picked:option(picked)?.label??picked,answered:option(answered2)?.label??answered2};return serverLine(conversationLanguage(threadId),option(picked)?.orgBlocked?"server.model.orgBlockedAnswered":"server.model.otherAnswered",names)}var ACCOUNT_FILE_MAX_BYTES,CLOUD_BACKEND_ENV,OFFICIAL_MODEL,told,init_claude_model_access=__esm({"server/drivers/claude-model-access.\
|
|
4216
4220
|
ts"(){"use strict";init_env_path();init_server_lines();init_setup_import();ACCOUNT_FILE_MAX_BYTES=32*1024*1024,CLOUD_BACKEND_ENV=["CLAUDE_CODE_USE_BEDROCK","CLAUDE_CODE_USE_FOUNDRY","CLAUDE_CODE_USE_ANTHROPIC_AWS","CLAUDE_CODE_USE_ANTHROPIC_GOOGLE_CLOUD","CLAUDE_CODE_USE_MANTLE","CLAUDE_CODE_USE_VERTEX"];OFFICIAL_MODEL=/^claude-[a-z0-9.-]+$/;told=new WeakMap}});function teamToolsFailed(server){let record12=server&&typeof server=="object"?server:null;return record12?.name==="agents"&&record12.status==="failed"}function failedCustomMcp(servers,custom2){if(!Array.isArray(servers)||!custom2)return{};let failed2=servers.flatMap(server=>{let record12=server&&typeof server=="object"?server:null;return typeof record12?.name=="string"&&record12.status==="failed"&&Object.hasOwn(custom2,record12.name)?[record12.name]:[]});return failed2.length?{mcpFailed:failed2}:
|
|
4217
|
-
{}}var TEAM_TOOLS_FAILED,init_team_tools=__esm({"server/drivers/team-tools.ts"(){"use strict";TEAM_TOOLS_FAILED="This bot's team tools didn't connect, so it couldn't reach other bots this time. They reconnect on your next message."}});var CLAUDE_OWN_MEMORY_OFF,init_claude_own_memory=__esm({"server/drivers/claude-own-memory.ts"(){"use strict";CLAUDE_OWN_MEMORY_OFF={CLAUDE_CODE_DISABLE_AUTO_MEMORY:"1"}}});import{mkdtempSync as mkdtempSync5,rmSync as rmSync18,writeFileSync as
|
|
4221
|
+
{}}var TEAM_TOOLS_FAILED,init_team_tools=__esm({"server/drivers/team-tools.ts"(){"use strict";TEAM_TOOLS_FAILED="This bot's team tools didn't connect, so it couldn't reach other bots this time. They reconnect on your next message."}});var CLAUDE_OWN_MEMORY_OFF,init_claude_own_memory=__esm({"server/drivers/claude-own-memory.ts"(){"use strict";CLAUDE_OWN_MEMORY_OFF={CLAUDE_CODE_DISABLE_AUTO_MEMORY:"1"}}});import{mkdtempSync as mkdtempSync5,rmSync as rmSync18,writeFileSync as writeFileSync14}from"node:fs";import{tmpdir as tmpdir7}from"node:os";import{join as join66}from"node:path";function keepWarmArgs(launchArgs,files,persist=!1){let kept=[];for(let i2=0;i2<launchArgs.length;i2++){let arg=launchArgs[i2];if(VALUE_FLAGS.has(arg)){i2++;continue}BARE_FLAGS.has(arg)||kept.push(arg)}return kept[0]!=="-p"&&kept.unshift("-p"),kept.push("--output-format","json"),files.systemPromptPath&&kept.push("--append\
|
|
4218
4222
|
-system-prompt-file",files.systemPromptPath),files.mcpConfigPath&&kept.push("--mcp-config",files.mcpConfigPath),files.settingsPath&&kept.push("--settings",files.settingsPath),kept.push("--resume",files.sessionId,"--fork-session",...persist?[]:["--no-session-persistence"]),kept}function keepWarmMcpServers(mcpServers,deadSocket){let out={...mcpServers},ogb=out.ogb;return ogb&&Array.isArray(ogb.args)&&ogb.args.length>=2&&(out.ogb={...ogb,args:[...ogb.args.slice(0,-1),deadSocket]}),out}function keepWarmSettings(settings2,denyCommand){
|
|
4219
4223
|
let{hooks:_harnessHooks,...rest}=settings2??{};return{...rest,hooks:{PreToolUse:[{matcher:"*",hooks:[{type:"command",command:denyCommand,timeout:10}]}]}}}function parseKeepWarmResult(stdout2,stderr,code){let frame=null;try{let parsed=JSON.parse(stdout2.trim());parsed&&typeof parsed=="object"&&!Array.isArray(parsed)&&(frame=parsed)}catch{}if(!frame||frame.type!=="result"){let said=(stderr.trim()||stdout2.trim()).split(`
|
|
4220
4224
|
`).pop()?.slice(0,300)??"";return{ok:!1,reason:said?`the ping failed: ${said}`:`the ping exited ${code??"without a code"}`}}let text13=typeof frame.result=="string"?frame.result:"";if(frame.is_error===!0){let limit=frame.api_error==="usage_limit_reached"||USAGE_LIMIT.test(text13);return{ok:!1,reason:limit?"the account's usage limit refused the ping":`the ping failed: ${text13.slice(0,300)||"API error"}`,...limit?{limit:!0}:{}}}let usage2=frame.usage??{},models2=frame.modelUsage&&typeof frame.modelUsage==
|
|
4221
4225
|
"object"&&!Array.isArray(frame.modelUsage)?Object.keys(frame.modelUsage):[];return{ok:!0,input:count3(usage2.input_tokens),cacheRead:count3(usage2.cache_read_input_tokens),cacheWrite:count3(usage2.cache_creation_input_tokens),output:count3(usage2.output_tokens),costUsd:typeof frame.total_cost_usd=="number"&&Number.isFinite(frame.total_cost_usd)?frame.total_cost_usd:null,model:models2[0]??null}}function forkSpawnOptions(contract,env,dir){return{cwd:contract.cwd,env,stdio:["pipe","pipe","pipe"],engineHome:!0,
|
|
4222
|
-
botWork:!0,box:{ro:[dir]}}}function runKeepWarmPing(opts){return runForkedPrompt({...opts,what:"ping",prompt:KEEP_WARM_PROMPT,persist:!1,timeoutMs:opts.timeoutMs??KEEP_WARM_TIMEOUT_MS,parse:parseKeepWarmResult,failed:reason=>({ok:!1,reason})})}function runForkedPrompt(opts){let{contract,what}=opts,dir;try{dir=mkdtempSync5(
|
|
4223
|
-
force:!0})}catch{}},args,env={...contract.env};try{let denyPath=
|
|
4224
|
-
|
|
4226
|
+
botWork:!0,box:{ro:[dir]}}}function runKeepWarmPing(opts){return runForkedPrompt({...opts,what:"ping",prompt:KEEP_WARM_PROMPT,persist:!1,timeoutMs:opts.timeoutMs??KEEP_WARM_TIMEOUT_MS,parse:parseKeepWarmResult,failed:reason=>({ok:!1,reason})})}function runForkedPrompt(opts){let{contract,what}=opts,dir;try{dir=mkdtempSync5(join66(tmpdir7(),"omb-keepwarm-"))}catch(error62){return Promise.resolve(opts.failed(`the ${what} could not start: ${error62.message}`))}let cleanup=()=>{try{rmSync18(dir,{recursive:!0,
|
|
4227
|
+
force:!0})}catch{}},args,env={...contract.env};try{let denyPath=join66(dir,"deny-tools.mjs");writeFileSync14(denyPath,KEEP_WARM_DENY_HOOK,{mode:384});let settingsPath=join66(dir,"settings.json");writeFileSync14(settingsPath,JSON.stringify(keepWarmSettings(contract.settings,`"${process.execPath}" "${denyPath}"`)),{mode:384});let mcpConfigPath=null;contract.mcpServers&&(mcpConfigPath=join66(dir,"mcp.json"),writeFileSync14(mcpConfigPath,JSON.stringify({mcpServers:keepWarmMcpServers(contract.mcpServers,
|
|
4228
|
+
join66(dir,"no-broker.sock"))}),{mode:384}));let systemPromptPath=null;contract.system&&(systemPromptPath=join66(dir,"prompt.txt"),writeFileSync14(systemPromptPath,contract.system,{mode:384})),args=keepWarmArgs(contract.args,{sessionId:opts.sessionId,mcpConfigPath,settingsPath,systemPromptPath},opts.persist);for(let key2 of Object.keys(env))key2.startsWith("OMB_HOOK_")&&delete env[key2];process.versions.electron&&(env.ELECTRON_RUN_AS_NODE="1")}catch(error62){return cleanup(),Promise.resolve(opts.
|
|
4225
4229
|
failed(`the ${what} could not start: ${error62.message}`))}return new Promise(resolve35=>{let child;try{child=spawnCli(opts.cli,args,forkSpawnOptions(contract,env,dir))}catch(error62){cleanup(),resolve35(opts.failed(`the ${what} could not start: ${error62.message}`));return}let stdout2="",stderr="",settled=!1,finish=result2=>{settled||(settled=!0,clearTimeout(timer2),opts.signal?.removeEventListener("abort",onAbort),cleanup(),resolve35(result2))},onAbort=()=>{killCliTree(child),finish(opts.failed(
|
|
4226
4230
|
`the ${what} was interrupted`))},timer2=setTimeout(()=>{killCliTree(child),finish(opts.failed(`the ${what} timed out`))},opts.timeoutMs);timer2.unref?.(),child.stdout.setEncoding("utf8"),child.stderr.setEncoding("utf8"),child.stdout.on("data",chunk=>{stdout2+=chunk,stdout2.length>1e6&&(killCliTree(child),finish(opts.failed(`the ${what}'s output exceeded 1 MB`)))}),child.stderr.on("data",chunk=>{stderr=(stderr+chunk).slice(-8192)}),child.on("error",error62=>finish(opts.failed(`the ${what} could n\
|
|
4227
4231
|
ot start: ${error62.message}`))),child.on("close",code=>finish(opts.parse(stdout2,stderr,code))),opts.signal?.aborted?onAbort():(opts.signal?.addEventListener("abort",onAbort,{once:!0}),child.stdin.on("error",()=>{}),child.stdin.end(opts.prompt))})}var KEEP_WARM_PROMPT,KEEP_WARM_TIMEOUT_MS,VALUE_FLAGS,BARE_FLAGS,KEEP_WARM_DENY_HOOK,count3,init_claude_keepwarm=__esm({"server/drivers/claude-keepwarm.ts"(){"use strict";init_procs();init_retry();KEEP_WARM_PROMPT="Reply with the single word: warm",KEEP_WARM_TIMEOUT_MS=
|
|
@@ -4235,25 +4239,25 @@ deps.holds.delete(threadId),parked.delete(threadId),!(why!=="idle"||!contract||!
|
|
|
4235
4239
|
ssion")||!deps.supports("--no-session-persistence")?{ok:!1,reason:"this Claude Code is too old to fork a session; update Claude Code"}:runKeepWarmPing({cli:deps.cli,contract,sessionId:live.sessionId,signal:options2?.signal})},hold:(threadId,until)=>{until===null?deps.holds.delete(threadId):deps.holds.set(threadId,until);let live=deps.live(threadId);return live?(live.turn||deps.armIdle(threadId),!0):!1},compact:async(threadId,options2)=>{let live=deps.live(threadId);if(live?.busy)return{ok:!1,reason:"\
|
|
4236
4240
|
a turn is running",busy:!0};let fork=forkOf(threadId,live);if(!fork)return{ok:!1,reason:"the conversation's Claude session has closed"};if(options2.session!==void 0&&fork.sessionId!==options2.session)return{ok:!1,reason:"the conversation moved to another session"};if(!deps.supports("--fork-session"))return{ok:!1,reason:"this Claude Code is too old to fork a session; update Claude Code"};let run6=await(deps.runSummary??runWarmSummary)({cli:deps.cli,contract:fork.contract,sessionId:fork.sessionId,
|
|
4237
4241
|
instructions:options2.instructions,signal:options2.signal});if(!run6.ok)return run6;if(options2.signal?.aborted||deps.live(threadId)?.busy)return{ok:!1,reason:"a turn started while summarizing",busy:!0};parked.delete(threadId),deps.summarized(threadId,run6);let{costTotal:_total,modelUsage:_usage,...result2}=run6;return result2}}}}var WARM_SUMMARY_TIMEOUT_MS,PARKED_FORK_MS,PARKED_MAX,INSTRUCTIONS_MAX,count4,init_claude_warm_summary=__esm({"server/drivers/claude-warm-summary.ts"(){"use strict";init_claude_keepwarm();
|
|
4238
|
-
init_retry();WARM_SUMMARY_TIMEOUT_MS=5*6e4,PARKED_FORK_MS=60*6e4,PARKED_MAX=200,INSTRUCTIONS_MAX=1500;count4=value=>typeof value=="number"&&Number.isFinite(value)&&value>=0?value:0}});import{mkdtempSync as mkdtempSync6,rmSync as rmSync19}from"node:fs";import{tmpdir as tmpdir8}from"node:os";import{join as
|
|
4239
|
-
"--strict-mcp-config"),input2.supports("--setting-sources")&&args.push("--setting-sources","project")),args}function spawnBackgroundCall(cli,args,env){let cwd=mkdtempSync6(
|
|
4240
|
-
init_claude_background=__esm({"server/drivers/claude-background.ts"(){"use strict";init_procs();BACKGROUND_CALL_TIMEOUT_MS=6e4,BACKGROUND_SETTINGS=JSON.stringify({alwaysThinkingEnabled:!1,disableAllHooks:!0})}});import{mkdirSync as
|
|
4241
|
-
function resolveClaudeConfigDir(configDir,env=process.env){let home2=env.HOME||env.USERPROFILE||
|
|
4242
|
+
init_retry();WARM_SUMMARY_TIMEOUT_MS=5*6e4,PARKED_FORK_MS=60*6e4,PARKED_MAX=200,INSTRUCTIONS_MAX=1500;count4=value=>typeof value=="number"&&Number.isFinite(value)&&value>=0?value:0}});import{mkdtempSync as mkdtempSync6,rmSync as rmSync19}from"node:fs";import{tmpdir as tmpdir8}from"node:os";import{join as join67}from"node:path";function backgroundCallArgs(input2){let args=["-p","--model",input2.model,"--output-format",input2.outputFormat,"--settings",BACKGROUND_SETTINGS];return input2.supports("--tools")&&args.push("--tools",""),input2.supports("--no-session-persistence")&&args.push("--no-session-persistence"),input2.isolated&&(input2.supports("--strict-mcp-config")&&args.push(
|
|
4243
|
+
"--strict-mcp-config"),input2.supports("--setting-sources")&&args.push("--setting-sources","project")),args}function spawnBackgroundCall(cli,args,env){let cwd=mkdtempSync6(join67(tmpdir8(),"omb-claude-background-")),removeCwd=()=>{try{rmSync19(cwd,{recursive:!0,force:!0,maxRetries:5,retryDelay:100})}catch{}};try{return{child:spawnCli(cli,args,{cwd,stdio:["pipe","pipe","pipe"],env,botWork:!0}),removeCwd}}catch(error62){throw removeCwd(),error62}}var BACKGROUND_CALL_TIMEOUT_MS,BACKGROUND_SETTINGS,
|
|
4244
|
+
init_claude_background=__esm({"server/drivers/claude-background.ts"(){"use strict";init_procs();BACKGROUND_CALL_TIMEOUT_MS=6e4,BACKGROUND_SETTINGS=JSON.stringify({alwaysThinkingEnabled:!1,disableAllHooks:!0})}});import{mkdirSync as mkdirSync26}from"node:fs";function withEndpointFolder(env,config3,onFail){if(!config3.endpointModels||!config3.configDir||!env.CLAUDE_CONFIG_DIR)return env;try{mkdirSync26(env.CLAUDE_CONFIG_DIR,{recursive:!0,mode:448})}catch(error62){throw onFail?.(),error62}return env}var init_claude_endpoint_folder=__esm({"server/drivers/claude-endpoint-folder.ts"(){"use strict"}});import{createHash as createHash19,randomBytes as randomBytes6,randomUUID as randomUUID13}from"node:crypto";import{chmodSync as chmodSync7,mkdirSync as mkdirSync27,mkdtempSync as mkdtempSync7,readFileSync as readFileSync35,rmSync as rmSync20,unlinkSync as unlinkSync7,writeFileSync as writeFileSync15}from"node:fs";import{createServer as createNetServer}from"node:net";import{homedir as homedir18,tmpdir as tmpdir9}from"node:os";import{join as join68,dirname as dirname30,isAbsolute as isAbsolute15,normalize}from"node:path";
|
|
4245
|
+
function resolveClaudeConfigDir(configDir,env=process.env){let home2=env.HOME||env.USERPROFILE||homedir18(),configured=configDir?.trim()||env.CLAUDE_CONFIG_DIR?.trim()||join68(home2,".claude"),expanded=configured==="~"?home2:configured.startsWith("~/")?join68(home2,configured.slice(2)):configured;if(!isAbsolute15(expanded)||/[\p{Cc}\p{Cf}]/u.test(expanded))throw new Error("claude: configDir must be an absolute path or start with ~/");return normalize(expanded)}function claudeResultError(frame){let errors=Array.
|
|
4242
4246
|
isArray(frame.errors)?frame.errors.filter(error62=>typeof error62=="string"&&error62.trim()!==""):[];return errors.length?errors.join("; "):typeof frame.result=="string"&&frame.result.trim()?claudeApiErrorMessage(frame,frame.result):`Claude ended the turn with an error (${String(frame.subtype!=="success"&&frame.subtype||frame.terminal_reason||"unknown")}).`}function claudeEnvironment(model,source=process.env,configDir,instanceEnvironment={},endpoint=!1,bedrock=!1){let env={BASH_MAX_TIMEOUT_MS:"6\
|
|
4243
4247
|
00000",...source,PATH:augmentedPath(),NPM_CONFIG_LOGLEVEL:"error"};if(configDir?.trim()?env.CLAUDE_CONFIG_DIR=resolveClaudeConfigDir(configDir,env):env.CLAUDE_CONFIG_DIR&&(env.CLAUDE_CONFIG_DIR=resolveClaudeConfigDir(void 0,env)),configDir?.trim()||endpoint||bedrock)for(let key2 of bedrock?[...CLAUDE_ACCOUNT_ENV_KEYS,...AWS_CREDENTIAL_ENV_KEYS]:CLAUDE_ACCOUNT_ENV_KEYS)(key2.startsWith("CLAUDE_CODE_OAUTH_")||key2.endsWith("_FILE_DESCRIPTOR")||!Object.hasOwn(instanceEnvironment,key2))&&delete env[key2];
|
|
4244
4248
|
return delete env.CLAUDECODE,delete env.CLAUDE_CODE_ENTRYPOINT,stripWorkspaceCredentialEnv(env),!applyClaudeInject(env,model).injected&&!instanceEnvironment.ANTHROPIC_API_KEY&&delete env.ANTHROPIC_API_KEY,env}function inheritsUserConfig(env){return env.OMB_CLAUDE_INHERIT_USER_CONFIG==="1"}function claudeInheritWarning(env){if(inheritsUserConfig(env))return{title:"Bots inherit this machine's Claude Code setup",message:"OMB_CLAUDE_INHERIT_USER_CONFIG=1 is set on the Limix Bot process, so every Cla\
|
|
4245
4249
|
ude bot also loads this computer's own MCP servers, connectors, skills, hooks and personal CLAUDE.md on every turn \u2014 often thousands of extra tokens per model call, and tools nobody gave the bot. Unless a bot genuinely needs a server from your user-scope Claude config, remove the variable and restart; add the server under Settings \u2192 MCP servers or the bot project's .mcp.json instead."}}function readClaudeAuthSettings(env,instanceEnvironment={}){if(CLAUDE_ACCOUNT_ENV_KEYS.some(key2=>instanceEnvironment[key2]))
|
|
4246
|
-
return{};try{let settings2=JSON.parse(
|
|
4250
|
+
return{};try{let settings2=JSON.parse(readFileSync35(join68(resolveClaudeConfigDir(void 0,env),"settings.json"),"utf8")),authEnv={};for(let key2 of CLAUDE_ACCOUNT_ENV_KEYS)!key2.endsWith("_FILE_DESCRIPTOR")&&typeof settings2?.env?.[key2]=="string"&&(authEnv[key2]=settings2.env[key2]);return{...Object.keys(authEnv).length?{env:authEnv}:{},...typeof settings2?.apiKeyHelper=="string"&&settings2.apiKeyHelper.trim()?{apiKeyHelper:settings2.apiKeyHelper}:{}}}catch{return{}}}function autoCompactWindow(env){
|
|
4247
4251
|
let raw=(env.OMB_CLAUDE_AUTOCOMPACT??"").trim().toLowerCase();if(raw==="off")return null;if(raw==="auto")return"auto";let parsed=raw?Number(raw):DEFAULT_AUTOCOMPACT_TOKENS;return!Number.isFinite(parsed)||parsed<=0?String(DEFAULT_AUTOCOMPACT_TOKENS):String(Math.min(1e6,Math.max(1e5,Math.floor(parsed))))}function parseClaudeCliVersion(stdout2){return parseVersionTriple(stdout2??"")}function claudeCliSupports(version2,flag3){return version2===null||versionAtLeast(version2,CLAUDE_FLAG_FLOORS[flag3])}
|
|
4248
4252
|
function claudeCliUpdate(version2,cli){let parsed=parseClaudeCliVersion(version2);if(!parsed||versionAtLeast(parsed,CLAUDE_CONTEXT_CONTROL_MIN_VERSION))return;let floor=CLAUDE_CONTEXT_CONTROL_MIN_VERSION.join("."),missing=Object.keys(CLAUDE_FLAG_FLOORS).filter(flag3=>!claudeCliSupports(parsed,flag3)),effects=[...missing.includes("--autocompact")?["no compaction window picked by Limix Bot"]:[],...missing.includes("--setting-sources")?["bots still see this machine's own Claude Code setup"]:[],...missing.
|
|
4249
4253
|
includes("--system-prompt-snapshot")?["resumed turns cannot refresh stale system prompts"]:[]];return{title:"Update Claude Code for context controls",message:`Claude Code ${parsed.join(".")} predates ${floor}, so bots run without ${missing.join(", ")}: ${effects.join("; ")}. Update it, then refresh Engines.`,command:cli==="claude"?"claude update":`${cli} update`}}async function resolveClaudeTurnModel(model,env,endpointModels){return endpointModels?model&&endpointModels.includes(model)?model:endpointModels[0]:
|
|
4250
|
-
!model||decodeInjectId(model)||currentEngineCatalog("claude").options.some(option=>option.id===model)?model:resolveInjectId(model,await probeLocalInjects(env))??model}function readClaudeModelCatalog(env=process.env){let settings2={};try{settings2=JSON.parse(
|
|
4254
|
+
!model||decodeInjectId(model)||currentEngineCatalog("claude").options.some(option=>option.id===model)?model:resolveInjectId(model,await probeLocalInjects(env))??model}function readClaudeModelCatalog(env=process.env){let settings2={};try{settings2=JSON.parse(readFileSync35(join68(resolveClaudeConfigDir(void 0,env),"settings.json"),"utf8"))}catch{settings2={}}let{extras,envModel}=claudeModelExtras(settings2,env),official2=currentEngineCatalog("claude"),options2=official2.options.map(option=>({...option})),
|
|
4251
4255
|
seen=new Set(options2.map(option=>option.id));for(let extra of extras)seen.has(extra.id)||(seen.add(extra.id),options2.push(extra.custom||extra.id===envModel?{id:extra.id,label:extra.label,custom:!0}:{id:extra.id,label:extra.label}));return{default:official2.default,options:options2}}function removePrivateTempDir(filePath){if(!filePath)return!0;try{return rmSync20(dirname30(filePath),{recursive:!0,force:!0,maxRetries:3,retryDelay:50}),!0}catch{return!1}}function systemEndedReply(kind){return kind===
|
|
4252
4256
|
"question"?{behavior:"answer",message:"Limix Bot: the turn is ending \u2014 wrap up."}:{behavior:"deny",message:"Limix Bot: the turn ended"}}function askQuestions(ask){return ask.tool===ASK_USER_QUESTION_TOOL||ask.tool===ASK_USER_TOOL?parseAskQuestions(ask.input):null}function askSummary(ask){let questions=askQuestions(ask);return questions?askQuestionSummary(questions):askInputSummary(ask.input)??ask.tool??"tool"}function sumNativeTurnResults(earlier,latest){if(!earlier)return latest;let usage2=earlier.
|
|
4253
4257
|
usage&&latest.usage?{input:earlier.usage.input+latest.usage.input,output:earlier.usage.output+latest.usage.output,...earlier.usage.cachedInput!==void 0||latest.usage.cachedInput!==void 0?{cachedInput:(earlier.usage.cachedInput??0)+(latest.usage.cachedInput??0)}:{}}:latest.usage??earlier.usage;return{ok:earlier.ok&&latest.ok,stopReason:latest.stopReason??earlier.stopReason,cost:latest.cost??earlier.cost,...usage2?{usage:usage2}:{}}}function hookTokenFile(threadId,botId){let digest4=createHash19("\
|
|
4254
|
-
sha256").update(`${botId??""}\0${threadId}`).digest("hex").slice(0,24);return
|
|
4258
|
+
sha256").update(`${botId??""}\0${threadId}`).digest("hex").slice(0,24);return join68(DATA_DIR,"hook-tokens",digest4,"token")}function claudeHookSettings(helperPath,platform=process.platform){let entry=[{matcher:"",hooks:[platform==="win32"?{type:"command",command:process.execPath,args:[helperPath],timeout:5}:{type:"command",command:[process.execPath,helperPath].map(path3=>`'${path3.replace(/'/g,"'\\''")}'`).join(" "),timeout:5}]}];return{PostToolUse:entry,PostToolUseFailure:entry,PreCompact:entry,
|
|
4255
4259
|
SessionStart:entry,Stop:entry}}function permissionSocketPath(threadId,botId){let key2=botId?`${botId}\0${threadId}`:threadId,prefix=threadId.replace(/[^\w-]/g,"").slice(0,4),digest4=createHash19("sha256").update(key2).digest("hex").slice(0,4);return brokerSocketPath(DATA_DIR,`${prefix}${digest4}`)}function brokerSocketCandidates(threadId,botId){let base2=permissionSocketPath(threadId,botId);if(process.platform!=="win32"){let scope=createHash19("sha256").update(`${DATA_DIR}\0${process.pid}\0${botId??
|
|
4256
|
-
""}\0${threadId}`).digest("hex").slice(0,16);return[base2,
|
|
4260
|
+
""}\0${threadId}`).digest("hex").slice(0,16);return[base2,join68(tmpdir9(),`omb-perm-${scope}.sock`)]}return[base2,`${base2}-${randomBytes6(3).toString("hex")}`,`${base2}-${randomBytes6(3).toString("hex")}`]}async function createPermissionBroker(opts){let timeoutMs=opts.timeoutMs??9e5,pending=new Map,closed=!1,boundPath=opts.socketPaths[0]??"",connectionHandler=conn=>{conn.on("error",()=>{}),conn.setEncoding("utf8");let buf="";conn.on("data",chunk=>{buf+=chunk;let nl;for(;(nl=buf.indexOf(`
|
|
4257
4261
|
`))!==-1;){let line3=buf.slice(0,nl);buf=buf.slice(nl+1);let msg;try{msg=JSON.parse(line3)}catch{continue}if(msg.t!=="ask")continue;let askId=String(msg.id??newId()),kind=msg.kind==="question"?"question":"permission";if(closed){try{conn.write(JSON.stringify({t:"answer",id:askId,...systemEndedReply(kind)})+`
|
|
4258
4262
|
`)}catch{}continue}if(opts.isActive&&!opts.isActive()){try{conn.write(JSON.stringify({t:"answer",id:askId,...systemEndedReply(kind)})+`
|
|
4259
4263
|
`)}catch{}continue}if(pending.has(askId)){console.error(`permission broker on ${boundPath}: duplicate ask id ${JSON.stringify(askId)} \u2014 denying`);try{conn.write(JSON.stringify({t:"answer",id:askId,behavior:"deny",message:DUPLICATE_ASK_ID_NOTE})+`
|
|
@@ -4268,7 +4272,7 @@ endpointModels!==void 0&&(o.managed===!0||o.managedModels!==void 0||!Array.isArr
|
|
|
4268
4272
|
"acceptEdits",...tools!==void 0?{tools}:{},...disallowedTools!==void 0?{disallowedTools}:{},...o.requireApiKey===!0?{requireApiKey:!0}:{},...o.bedrock===!0?{bedrock:!0}:{}}}function firstText(content3){return typeof content3=="string"?content3:Array.isArray(content3)?content3.filter(b3=>b3?.type==="text"&&b3.text).map(b3=>b3.text).join(""):""}function turnCostFromRunningTotal(total,previous2){return total===null?null:previous2===null||total<previous2?total:Number((total-previous2).toFixed(10))}function claudeCostSnapshot(total,modelUsage){
|
|
4269
4273
|
if(typeof total!="number"||!Number.isFinite(total))return null;let count5=value=>typeof value=="number"&&Number.isFinite(value)?value:0,models2={};if(modelUsage&&typeof modelUsage=="object"&&!Array.isArray(modelUsage))for(let[model,raw]of Object.entries(modelUsage)){if(!raw||typeof raw!="object")continue;let u5=raw;models2[model]=[count5(u5.inputTokens),count5(u5.cacheReadInputTokens),count5(u5.cacheCreationInputTokens),count5(u5.outputTokens)]}return{total,models:models2}}function restoredCostBase(earlier,current,usage2){
|
|
4270
4274
|
let turn=[usage2.input,usage2.cacheRead,usage2.cacheWrite,usage2.output],nothing={total:0,models:{}},exact=null,inside3=0;for(let state of[nothing,...earlier]){if(!Object.entries(state.models).every(([model,counts])=>counts.every((n3,i2)=>n3<=(current.models[model]?.[i2]??0))))continue;inside3=state.total;let growth=Object.entries(current.models).map(([model,counts])=>counts.map((n3,i2)=>n3-(state.models[model]?.[i2]??0))),isTurn=counts=>counts.every((n3,i2)=>n3===turn[i2]),summed=turn.map((_3,i2)=>growth.
|
|
4271
|
-
reduce((sum,counts)=>sum+counts[i2],0));(growth.some(isTurn)||isTurn(summed))&&(exact=state.total)}return exact??inside3}function claudeUserMessage(text13,images){if(!images?.length)return{type:"user",message:{role:"user",content:text13}};let content3=images.map(image=>({type:"image",source:{type:"base64",media_type:image.mime,data:
|
|
4275
|
+
reduce((sum,counts)=>sum+counts[i2],0));(growth.some(isTurn)||isTurn(summed))&&(exact=state.total)}return exact??inside3}function claudeUserMessage(text13,images){if(!images?.length)return{type:"user",message:{role:"user",content:text13}};let content3=images.map(image=>({type:"image",source:{type:"base64",media_type:image.mime,data:readFileSync35(image.path).toString("base64")}}));return text13&&content3.push({type:"text",text:text13}),{type:"user",message:{role:"user",content:content3}}}function diagnosticClaudeUserMessage(message5){
|
|
4272
4276
|
return Array.isArray(message5.message.content)?{...message5,message:{...message5.message,content:message5.message.content.map(block2=>block2.type==="image"?{...block2,source:{...block2.source,data:`[image data: ${block2.source.data.length} base64 chars]`}}:block2)}}:message5}var CLAUDE_ACCOUNT_ENV_KEYS,DEFAULT_AUTOCOMPACT_TOKENS,CLAUDE_FLAG_FLOORS,withWhy,GUEST_CLAUDE_TOOLS,GUEST_FORBIDDEN_TOOLS,GUEST_CLAUDE_PERMISSIONS,CLAUDE_CONTEXT_CONTROL_MIN_VERSION,CLAUDE_REPLAY_FLOOR,DRIVER_KIND,NO_ANTHROPIC_KEY,
|
|
4273
4277
|
PERM_PROXY_PATH,DWEB_PROXY_PATH,HOOK_HELPER_PATH,NODE_ENV_FLAG,DENY_TIMEOUT_NOTE,DUPLICATE_ASK_ID_NOTE,STEERED_CONTINUATION_GRACE_MS,STEERED_CONTINUATION_SILENCE_MS,fakeTimerScale,steerGraceScale,steerSilenceScale,ClaudeDriver,init_claude=__esm({"server/drivers/claude.ts"(){"use strict";init_config3();init_startup_model_catalog();init_atomic();init_env_path();init_procs();init_cli_version_probe();init_claude_auth_status();init_claude_project_mcp();init_claude_bot_settings();init_claude_billing();
|
|
4274
4278
|
init_claude_auth_recovery();init_claude_bedrock_aws();init_claude_model_extras();init_claude_tool_search();init_claude_unusable_tools();init_email();init_claude_elicitation();init_claude_cost_history();init_resume_recovery();init_claude_login_auth();init_mcp_gate_config();init_tool_scope();init_tool_scope_support();init_contracts();init_tool_summary();init_retry();init_claude_limits();init_claude_model_access();init_engine_homes();init_team_tools();init_session_idle();init_prompt_split();init_claude_own_memory();
|
|
@@ -4301,19 +4305,19 @@ integrations.phone},allowed2.push("mcp__phone")),turn.integrations?.browser&&(mc
|
|
|
4301
4305
|
__${tool}`))),turn.integrations?.dweb&&(mcpServers.dweb={command:process.execPath,args:[DWEB_PROXY_PATH],env:{...NODE_ENV_FLAG,DWEB_URL:turn.integrations.dweb.url}},allowed2.push("mcp__dweb"));let botOwned=new Set;for(let[name,server]of Object.entries(turn.integrations?.custom??{}))Object.hasOwn(mcpServers,name)||(mcpServers[name]={...server},botOwned.add(name));if(isolated&&turn.cwd&&!turn.guestConfined)for(let[name,server]of Object.entries(projectMcpServers(turn.cwd)))Object.hasOwn(mcpServers,
|
|
4302
4306
|
name)||(mcpServers[name]=server,botOwned.add(name));for(let name of turn.toolScope===void 0?botOwned:Object.keys(mcpServers)){if(!canUseMcpServer(turn.toolScope,name)){delete mcpServers[name];continue}let gated=gateServer({name,server:mcpServers[name],threadId,nodeEnv:NODE_ENV_FLAG,toolScope:turn.toolScope,...customServerGate(name,botOwned.has(name),turn.integrations?.customResultBudgets,turnEnvironment),apps:appMountFor(name,turn)});gated&&(mcpServers[name]={...gated,...mcpServers[name]?.alwaysLoad===
|
|
4303
4307
|
!0?{alwaysLoad:!0}:{}})}allowed2.splice(0,allowed2.length,...allowed2.filter(name=>Object.hasOwn(mcpServers,name.slice(5).split("__")[0])));let broker,socketPath=permissionSocketPath(threadId,botId);permissionMode!=="bypassPermissions"&&args.push("--permission-prompt-tool","mcp__ogb__approve");let permissionEnv={...NODE_ENV_FLAG,...turn.toolScope!==void 0?{OMB_PERMISSION_TOOL_SCOPE:JSON.stringify(turn.toolScope)}:{}};mcpServers.ogb={command:process.execPath,args:[PERM_PROXY_PATH,socketPath],env:permissionEnv,
|
|
4304
|
-
alwaysLoad:!0},allowed2.push("mcp__ogb",...gateQueryTools(mcpServers)),turn.guestConfined&&allowed2.splice(0,allowed2.length,...allowed2.filter(name=>name==="mcp__ogb"||name==="mcp__agents"));let env=withEndpointFolder(environment(config3.endpointModels?void 0:turnModel),config3,()=>retryState.delete(threadId)),mcpConfigPath=null;Object.keys(mcpServers).length&&(mcpConfigPath=
|
|
4305
|
-
dTools",allowed2.join(",")));let authSettings=isolated&&!injected.injected?readClaudeAuthSettings(env,input2.environment):{},hooks=turn.integrations?.hooks,hookTokenPath=hooks?hookTokenFile(threadId,botId):null;hooks&&hookTokenPath&&(
|
|
4306
|
-
cwd??
|
|
4307
|
-
settings2=withBotSettings(botSettings,own4),authSettingsPath=mcpConfigPath&&Object.keys(settings2).length?
|
|
4308
|
+
alwaysLoad:!0},allowed2.push("mcp__ogb",...gateQueryTools(mcpServers)),turn.guestConfined&&allowed2.splice(0,allowed2.length,...allowed2.filter(name=>name==="mcp__ogb"||name==="mcp__agents"));let env=withEndpointFolder(environment(config3.endpointModels?void 0:turnModel),config3,()=>retryState.delete(threadId)),mcpConfigPath=null;Object.keys(mcpServers).length&&(mcpConfigPath=join68(mkdtempSync7(join68(tmpdir9(),"omb-mcp-")),"mcp.json"),args.push("--mcp-config",mcpConfigPath),args.push("--allowe\
|
|
4309
|
+
dTools",allowed2.join(",")));let authSettings=isolated&&!injected.injected?readClaudeAuthSettings(env,input2.environment):{},hooks=turn.integrations?.hooks,hookTokenPath=hooks?hookTokenFile(threadId,botId):null;hooks&&hookTokenPath&&(mkdirSync27(dirname30(hookTokenPath),{recursive:!0,mode:448}),writeFileAtomicIfChanged(hookTokenPath,hooks.token,{mode:384,durable:!1}),env.OMB_HOOK_URL=hooks.url,env.OMB_HOOK_TOKEN_FILE=hookTokenPath,process.versions.electron&&(env.ELECTRON_RUN_AS_NODE="1"));let cwd=turn.
|
|
4310
|
+
cwd??homedir18(),toolSearch=claudeToolSearchSetting(cwd,env),own4={...authSettings,env:{...authSettings.env,ENABLE_TOOL_SEARCH:toolSearch,...isolated?CLAUDE_OWN_MEMORY_OFF:{}}};isolated&&(own4.claudeMdExcludes=[join68(homedir18(),".claude","CLAUDE.md")]),hooks&&(own4.hooks=claudeHookSettings(HOOK_HELPER_PATH)),turn.guestConfined&&(own4.permissions=GUEST_CLAUDE_PERMISSIONS),env.CLAUDE_CODE_DISABLE_BACKGROUND_TASKS="1";let botSettings=turn.guestConfined?{}:botSettingsFor(turn.botSettingsFile,cwd,env),
|
|
4311
|
+
settings2=withBotSettings(botSettings,own4),authSettingsPath=mcpConfigPath&&Object.keys(settings2).length?join68(dirname30(mcpConfigPath),"auth-settings.json"):null;authSettingsPath&&args.push("--settings",authSettingsPath);let commandCwd=permissionLaunchCwd(cwd),privateFileFlags=new Set(["--mcp-config","--settings"]),keyArgs=args.filter((a2,i2)=>!privateFileFlags.has(a2)&&!privateFileFlags.has(args[i2-1]??"")),argsKey=JSON.stringify({args:keyArgs,system:turn.systemStable??turn.system??null,mcpServers,
|
|
4308
4312
|
cwd,model:injected.model??null,base:env.ANTHROPIC_BASE_URL??null,configDir:env.CLAUDE_CONFIG_DIR??null,hooks:!!hooks,toolSearch,botSettings:createHash19("sha256").update(JSON.stringify(botSettings)).digest("hex"),auth:createHash19("sha256").update(JSON.stringify({settings:authSettings,env:Object.fromEntries(CLAUDE_ACCOUNT_ENV_KEYS.map(key2=>[key2,env[key2]]))})).digest("hex")}),live=sessions.get(threadId);if(!turn.sessionReset&&live&&!live.turn&&!live.closing&&live.child.exitCode===null&&live.argsKey===
|
|
4309
4313
|
argsKey&&(!sessionId||sessionId===live.sessionId)){live.idleTimer&&clearTimeout(live.idleTimer),live.turn={turnId,input:turn,retryAbort,settled:!1,sawStreamDelta:!1,awaitingInit:!0,pendingSteers:new Set,deferred:null,continuationGrace:null,continuationSilence:null},active.set(threadId,{stop:()=>{live.turn&&(live.turn.stopRequested=!0),closeSession(threadId,"interrupted"),retry.cancelled=!0,retryAbort.abort(),stopSession(live)},turnId,broker:live.broker}),emit({...base2(threadId,turnId),type:"tur\
|
|
4310
4314
|
n.started"});let volatile=turn.systemVolatile??"",message5=!turn.mentionTurn&&(volatile===live.volatile||live.volatile===null&&!volatile.trim())?promptMsg:claudeUserMessage(withVolatileNote(turn.text,volatile,live.volatile===null),turn.images);live.volatile=volatile;let running4=live.turn;if(!await writeUser(live,threadId,message5)&&!running4?.stopRequested&&closeSession(threadId,"stdin write failed"),mcpConfigPath)try{rmSync20(dirname30(mcpConfigPath),{recursive:!0,force:!0})}catch{}return{turnId}}
|
|
4311
|
-
live&&closeSession(threadId,turn.sessionReset?"context reset":"spawn contract changed");let halves=promptHalves(turn),launchSystem=halves.stable??turn.system,cleanupUnownedLaunch=()=>{if(broker?.close(),broker=void 0,mcpConfigPath){try{rmSync20(dirname30(mcpConfigPath),{recursive:!0,force:!0})}catch{}mcpConfigPath=null}systemPromptPath&&(removePrivateTempDir(systemPromptPath),systemPromptPath=null),retryState.delete(threadId)};try{if(launchSystem&&(systemPromptPath=
|
|
4312
|
-
"omb-system-")),"prompt.txt"),
|
|
4315
|
+
live&&closeSession(threadId,turn.sessionReset?"context reset":"spawn contract changed");let halves=promptHalves(turn),launchSystem=halves.stable??turn.system,cleanupUnownedLaunch=()=>{if(broker?.close(),broker=void 0,mcpConfigPath){try{rmSync20(dirname30(mcpConfigPath),{recursive:!0,force:!0})}catch{}mcpConfigPath=null}systemPromptPath&&(removePrivateTempDir(systemPromptPath),systemPromptPath=null),retryState.delete(threadId)};try{if(launchSystem&&(systemPromptPath=join68(mkdtempSync7(join68(tmpdir9(),
|
|
4316
|
+
"omb-system-")),"prompt.txt"),writeFileSync15(systemPromptPath,launchSystem,{mode:384}),args.push("--append-system-prompt-file",systemPromptPath)),socketPath){let askTools=new Map;broker=await createPermissionBroker({socketPaths:brokerSocketCandidates(threadId,botId),isActive:()=>!!sessions.get(threadId)?.turn,onAsk:ask=>{let eventTurnId=sessions.get(threadId)?.turn?.turnId??turnId;askTools.set(ask.id,typeof ask.tool=="string"?ask.tool:void 0);let nativeMode=sessions.get(threadId)?.nativePermissionMode??
|
|
4313
4317
|
null,nativeReview=permissionMode==="auto"&&nativeMode!==null?nativeMode==="auto"?"active":"inactive":void 0,questions=askQuestions(ask);emit({...base2(threadId,eventTurnId),type:"request.opened",requestId:ask.id,requestType:ask.kind,tool:ask.tool,summary:askSummary(ask),...shellRequest(ask.kind==="permission"&&ask.tool==="Bash"?ask.input.command:void 0,commandCwd),...ask.kind==="permission"&&readToolPaths(ask.tool,ask.input)?{reads:readToolPaths(ask.tool,ask.input)}:{},requiresExplicitApproval:ask.
|
|
4314
4318
|
kind==="permission"&&ask.tool==="Bash"&&ask.input.dangerouslyDisableSandbox===!0||void 0,nativeReview,allowSession:ask.kind==="permission"&&!(controlsHost&&typeof ask.tool=="string"&&ask.tool.startsWith("mcp__computer"))?!0:void 0,approvalScope:typeof ask.tool=="string"&&controlsHost&&ask.tool.startsWith("mcp__computer")?"local-computer":void 0,questions:questions??void 0,choices:questions?questionChoices(questions):parseChoices(ask.input?.choices)})},onResolve:resolved2=>{let eventTurnId=sessions.
|
|
4315
4319
|
get(threadId)?.turn?.turnId??turnId;emit({...base2(threadId,eventTurnId),type:"request.resolved",requestId:resolved2.id,behavior:resolved2.behavior,source:resolved2.source,approvalScope:controlsHost&&typeof askTools.get(resolved2.id)=="string"&&askTools.get(resolved2.id).startsWith("mcp__computer")?"local-computer":void 0}),askTools.delete(resolved2.id)}}),broker.socketPath!==socketPath&&mcpConfigPath&&(mcpServers.ogb={command:process.execPath,args:[PERM_PROXY_PATH,broker.socketPath],env:permissionEnv,
|
|
4316
|
-
alwaysLoad:!0})}mcpConfigPath&&
|
|
4320
|
+
alwaysLoad:!0})}mcpConfigPath&&writeFileSync15(mcpConfigPath,JSON.stringify({mcpServers}),{mode:384}),authSettingsPath&&writeFileSync15(authSettingsPath,JSON.stringify(settings2),{mode:384}),sessionId?args.push("--resume",sessionId):args.push("--session-id",newSessionId)}catch(error62){throw cleanupUnownedLaunch(),error62}if(relaunch&&retry.cancelled)return cleanupUnownedLaunch(),active.get(threadId)?.turnId===turnId&&active.delete(threadId),emit({...base2(threadId,turnId),type:"turn.completed",
|
|
4317
4321
|
ok:!1,stopReason:"interrupted",cost:null}),{turnId};let child;try{child=spawnCli(config3.cli,args,{cwd,env,stdio:["pipe","pipe","pipe"],box:{...broker?{rw:[broker.socketPath]}:{},...hookTokenPath?{ro:[dirname30(hookTokenPath)]}:{}}},"bot")}catch(error62){throw cleanupUnownedLaunch(),error62}turn.guestConfined?warmContracts.delete(threadId):warmContracts.set(threadId,{args:[...args],env:{...env},cwd,system:launchSystem??null,mcpServers:mcpConfigPath?JSON.parse(JSON.stringify(mcpServers)):null,settings:authSettingsPath?
|
|
4318
4322
|
JSON.parse(JSON.stringify(settings2)):null});let markClosed,session={closed:new Promise(resolve35=>{markClosed=resolve35}),child,broker,elicit:claudeElicitations(frame=>new Promise(resolve35=>{let{stdin:stdin2}=session.child;if(!stdin2.writable||stdin2.destroyed)return resolve35(!1);try{stdin2.write(`${JSON.stringify(frame)}
|
|
4319
4323
|
`,err=>resolve35(!err))}catch{resolve35(!1)}}),event=>emit({...base2(threadId,session.turn?.turnId??turnId),...event})),mcpConfigPath,systemPromptPath,argsKey,cliVersion:cliHelpVersion,passedAutocompact,volatile:turn.systemVolatile??"",sessionId:sessionId??newSessionId,sawInit:!1,nativePermissionMode:null,replaysUserMessages,turn:{turnId,input:turn,retryAbort,settled:!1,sawStreamDelta:!1,pendingSteers:new Set,deferred:null,continuationGrace:null,continuationSilence:null},idleTimer:null,closing:!1,
|
|
@@ -4369,10 +4373,10 @@ https:"&&!(url3.protocol==="http:"&&loopback))throw new Error(`Invalid ${label2}
|
|
|
4369
4373
|
"-c","shell_environment_policy.ignore_default_excludes=false"]}var init_codex_endpoint_config=__esm({"server/drivers/codex-endpoint-config.ts"(){"use strict"}});function codexActionFailure(message5,mayHaveRun,text13){return mayHaveRun?noticeFailure("chat.notice.codexActionMayHaveRun",{message:message5}):{message:message5,...text13?{text:text13}:{}}}var init_codex_action_notice=__esm({"server/drivers/codex-action-notice.ts"(){"use strict";init_chat_notices()}});function codexToolSurfaceArgs(){return["-c","features.browser_use=false","-c","features.browser_use_external=false","-c","features.computer_use=false","-c",'plugins={ "browser@openai-bundled" = { enabled = false }, "computer-use@openai-bundled" = { enabled = false }, "unified-computer-use@openai-bundled" = { enabled = false } }']}var init_codex_tool_surface=__esm({"server/drivers/codex-tool-surface.ts"(){"use strict"}});function codexShellDisabled(config3){let features=plainRecord(plainRecord(config3)?.features);return features?.shell_tool===!1&&features?.unified_exec===!1&&features?.view_image===!1}function codexDisabledNativeSkillArgs(botId){let names=disabledNativeSkillNames(botId??"");return names.length?["-c",`skills.config=[${names.map(name=>`{name=${JSON.stringify(name)},enabled=false}`).join(",")}]`]:[]}function codexTurnConfigArgs(turn){return[...turn.guestConfined?GUEST_CONFINED_CODEX_ARGS:[],...codexDisabledNativeSkillArgs(
|
|
4370
4374
|
turn.botId)]}var plainRecord,GUEST_CONFINED_CODEX_ARGS,init_codex_guest=__esm({"server/drivers/codex-guest.ts"(){"use strict";init_native_skill_choices();plainRecord=value=>value&&typeof value=="object"&&!Array.isArray(value)?value:null,GUEST_CONFINED_CODEX_ARGS=["-c","features.shell_tool=false","-c","features.unified_exec=false","-c","features.view_image=false","-c",'web_search="disabled"']}});function supportsMcpStartup(userAgent){let match=typeof userAgent=="string"?userAgent.match(/\/(\d+)\.(\d+)\.(\d+)/):null;return match?Number(match[1])>0||Number(match[2])>=117:!0}function enabledMcpMounts(names,config3,scoped){if(scoped)return[...names];let servers=config3?.mcp_servers;return names.filter(name=>servers?.[name]?.enabled!==!1)}function mcpStartupTracker(appServer){let states2=new Map,waiters=new Set,exited=new AbortController;return appServer.once("exit",()=>exited.abort()),{record(update){
|
|
4371
4375
|
let record12=update&&typeof update=="object"?update:null;if(!(typeof record12?.name!="string"||typeof record12.status!="string")){states2.set(record12.name,record12.status);for(let wake of waiters)wake()}},async settled(names,signal,timeoutMs=MCP_STARTUP_WAIT_MS){let stop=AbortSignal.any([signal,exited.signal]),done=()=>names.every(name=>SETTLED_STATES.has(states2.get(name)??""));return!stop.aborted&&!done()&&await new Promise(resolve35=>{let finish=()=>{clearTimeout(timer2),waiters.delete(check3),
|
|
4372
|
-
stop.removeEventListener("abort",finish),resolve35()},check3=()=>{done()&&finish()},timer2=setTimeout(finish,timeoutMs);timer2.unref?.(),waiters.add(check3),stop.addEventListener("abort",finish,{once:!0})}),!stop.aborted}}}var SETTLED_STATES,MCP_STARTUP_WAIT_MS,init_codex_mcp_startup=__esm({"server/drivers/codex-mcp-startup.ts"(){"use strict";SETTLED_STATES=new Set(["ready","failed","cancelled"]),MCP_STARTUP_WAIT_MS=3e4}});import{existsSync as
|
|
4376
|
+
stop.removeEventListener("abort",finish),resolve35()},check3=()=>{done()&&finish()},timer2=setTimeout(finish,timeoutMs);timer2.unref?.(),waiters.add(check3),stop.addEventListener("abort",finish,{once:!0})}),!stop.aborted}}}var SETTLED_STATES,MCP_STARTUP_WAIT_MS,init_codex_mcp_startup=__esm({"server/drivers/codex-mcp-startup.ts"(){"use strict";SETTLED_STATES=new Set(["ready","failed","cancelled"]),MCP_STARTUP_WAIT_MS=3e4}});import{existsSync as existsSync29}from"node:fs";import{cpus}from"node:os";function codexLaunchLimit(){let configured=Number(process.env.OMB_CODEX_LAUNCH_SLOTS);return Number.isInteger(configured)&&configured>0?configured:Math.max(2,cpus().length)}function tryCodexLaunchSlot(){if(starting>=codexLaunchLimit())return null;starting++;let held3=!0;return()=>{if(held3)for(held3=!1,starting--;waiting.length&&!waiting.shift()(););}}function codexLaunchesStarting(){return starting}function codexLaunchSlot(signal){
|
|
4373
4377
|
return new Promise(resolve35=>{if(signal.aborted)return resolve35(null);let take2=()=>{let slot=tryCodexLaunchSlot();return slot?(signal.removeEventListener("abort",abort),resolve35(slot),!0):!1},abort=()=>{let index2=waiting.indexOf(take2);index2>=0&&waiting.splice(index2,1),resolve35(null)};take2()||(waiting.push(take2),signal.addEventListener("abort",abort,{once:!0}))})}function spawnHoldingSlot(release2,spawn12){try{let child=spawn12();return child.once("exit",release2).once("error",release2),
|
|
4374
4378
|
child}catch(error62){throw release2(),error62}}function codexRpcTimeoutMs(method){return STARTUP_METHODS.has(method)?18e4:6e4}async function keepStopping(stop,owned){let everyMs=Math.max(1,Number(process.env.FAKE_CODEX_STOP_RETRY_MS)||5e3);for(let attempt=0;attempt<12&&owned();attempt++)if(await new Promise(resolve35=>setTimeout(resolve35,everyMs).unref?.()),owned()&&await stop())return!0;return!1}function tomlInlineTable(entries2){return`{ ${Object.entries(entries2).map(([key2,value])=>`${JSON.
|
|
4375
|
-
stringify(key2)} = ${JSON.stringify(value)}`).join(", ")} }`}function codexCliOverrides(cli){let unchanged={cli,overrides:[]},trimmed=cli.trim();if(trimmed.includes(" ")&&
|
|
4379
|
+
stringify(key2)} = ${JSON.stringify(value)}`).join(", ")} }`}function codexCliOverrides(cli){let unchanged={cli,overrides:[]},trimmed=cli.trim();if(trimmed.includes(" ")&&existsSync29(trimmed))return unchanged;let[head,...rest]=splitCliString(trimmed);if(!head||rest.length===0)return unchanged;let kept=[head],overrides2=[];for(let index2=0;index2<rest.length;index2++){let token=rest[index2],next=rest[index2+1];(token==="-c"||token==="--config")&&next?.includes("=")?(overrides2.push("-c",next),index2++):
|
|
4376
4380
|
token.startsWith("--config=")&&token.slice(9).includes("=")?overrides2.push("-c",token.slice(9)):kept.push(token)}if(overrides2.length===0)return unchanged;let quoted2=kept.map(token=>/[\s"']/.test(token)?token.includes('"')?token.includes("'")?null:`'${token}'`:`"${token}"`:token);return quoted2.includes(null)?unchanged:{cli:quoted2.join(" "),overrides:overrides2}}function codexLaunch(cli,appServerArgs){let launch=codexCliOverrides(cli),[subcommand,...driverArgs]=appServerArgs;return[launch.cli,
|
|
4377
4381
|
[subcommand,...launch.overrides,...driverArgs]]}var starting,waiting,STARTUP_METHODS,RELAUNCH_EXIT_WAIT_MS,init_codex_process=__esm({"server/drivers/codex-process.ts"(){"use strict";init_env_path();starting=0,waiting=[];STARTUP_METHODS=new Set(["initialize","config/read","thread/start","thread/resume","thread/unarchive","turn/start"]);RELAUNCH_EXIT_WAIT_MS=3e4}});function mountMcpServer(appServerArgs,env,name,server,approval="auto",literalEnv={},written=new Set,forward=[]){let prefix=`mcp_servers.${name}`;Object.assign(env,server.env);for(let name2 of Object.keys(server.env))written.add(name2);appServerArgs.push("-c",`${prefix}.command=${JSON.stringify(server.command)}`,"-c",`${prefix}.args=${JSON.stringify(server.args)}`,"-c",`${prefix}.env_vars=${JSON.stringify([...new Set([...Object.keys(server.env),...forward])])}`),Object.keys(literalEnv).length&&appServerArgs.
|
|
4378
4382
|
push("-c",`${prefix}.env=${tomlInlineTable(literalEnv)}`),approval!=="prompt"&&appServerArgs.push("-c",`${prefix}.default_tools_approval_mode="${approval}"`)}function boxProxyEnvNames(boxed=botBox.enabled()){return boxed?[...BOX_PROXY_ENV,...BOX_NO_PROXY_ENV]:[]}function customServerEnvBox(custom2,mounted){let configured=new Set(Object.values(custom2??{})),names=[...new Set([...mounted.values()].filter(server=>configured.has(server)).flatMap(server=>Object.keys(server.env)))];return names.length?
|
|
@@ -4380,8 +4384,8 @@ push("-c",`${prefix}.env=${tomlInlineTable(literalEnv)}`),approval!=="prompt"&&a
|
|
|
4380
4384
|
payload.output))?.[1]}function unsupportedCallsIn(text13){let bytes2=typeof text13=="string"?Buffer.from(text13,"utf8"):text13,tools=new Set;for(let at2=bytes2.indexOf(MARKER2);at2!==-1;){let start=bytes2.lastIndexOf(NEWLINE,at2)+1,newline=bytes2.indexOf(NEWLINE,at2),end=newline===-1?bytes2.length:newline,tool=refusedTool(bytes2.subarray(start,end).toString("utf8"));if(tool&&tools.add(tool),newline===-1)break;at2=bytes2.indexOf(MARKER2,end)}return[...tools]}function unsupportedCallsSince(mark,maxBytes=ROLLOUT_SCAN_MAX_BYTES){
|
|
4381
4385
|
if(!mark)return[];let fd;try{fd=openSync12(mark.path,"r");let end=fstatSync6(fd).size,from=end<mark.offset?0:mark.offset,length2=Math.min(end-from,maxBytes);if(length2<=0)return[];let bytes2=Buffer.alloc(length2),read2=readSync6(fd,bytes2,0,length2,from);return unsupportedCallsIn(bytes2.subarray(0,read2))}catch{return[]}finally{fd!==void 0&&closeSync13(fd)}}function unsupportedCallsFailure(tools){let key2=tools.length>6?"chat.notice.codexUnsupportedMore":tools.length===1?"chat.notice.codexUnsupp\
|
|
4382
4386
|
ortedOne":"chat.notice.codexUnsupportedMany";return noticeFailure(key2,{tools:tools.slice(0,6).join(", "),...tools.length>6?{count:String(tools.length-6)}:{}})}function reportUnsupportedCalls(mark,notice){let tools=unsupportedCallsSince(mark);if(!tools.length)return;console.warn(`[codex] unsupported tool call (provider dropped the MCP namespace): ${tools.join(", ")}`);let failure2=unsupportedCallsFailure(tools);notice(failure2.message,failure2.text)}var ROLLOUT_SCAN_MAX_BYTES,UNSUPPORTED,MARKER2,
|
|
4383
|
-
NEWLINE,outputText,init_codex_unsupported_calls=__esm({"server/drivers/codex-unsupported-calls.ts"(){"use strict";init_chat_notices();ROLLOUT_SCAN_MAX_BYTES=16*1024*1024,UNSUPPORTED=/^unsupported call: ([\w.:-]{1,200})/,MARKER2="unsupported call: ",NEWLINE=10;outputText=output2=>typeof output2=="string"?output2:Array.isArray(output2)?output2.map(part=>typeof part?.text=="string"?part.text:"").join(""):output2&&typeof output2=="object"&&typeof output2.content=="string"?output2.content:""}});import{readFileSync as
|
|
4384
|
-
try{text13=
|
|
4387
|
+
NEWLINE,outputText,init_codex_unsupported_calls=__esm({"server/drivers/codex-unsupported-calls.ts"(){"use strict";init_chat_notices();ROLLOUT_SCAN_MAX_BYTES=16*1024*1024,UNSUPPORTED=/^unsupported call: ([\w.:-]{1,200})/,MARKER2="unsupported call: ",NEWLINE=10;outputText=output2=>typeof output2=="string"?output2:Array.isArray(output2)?output2.map(part=>typeof part?.text=="string"?part.text:"").join(""):output2&&typeof output2=="object"&&typeof output2.content=="string"?output2.content:""}});import{readFileSync as readFileSync36}from"node:fs";import{homedir as homedir19}from"node:os";import{join as join69}from"node:path";import{isDeepStrictEqual}from"node:util";function mcpServerNamesInToml(toml){let names=new Set;for(let match of toml.matchAll(HEADER)){let name=match[1]!==void 0?match[1].replace(/\\(.)/g,"$1"):match[2]??match[3];name&&names.add(name)}return names}function codexConfigMcp(env){let codexHome2=env.CODEX_HOME||join69(env.HOME||env.USERPROFILE||homedir19(),".codex"),text13="";
|
|
4388
|
+
try{text13=readFileSync36(join69(codexHome2,"config.toml"),"utf8")}catch{}let tables={};try{let servers=parseToml(text13).mcp_servers;return isRecord7(servers)&&(tables=servers),{names:new Set(Object.keys(tables)),tables}}catch{}return{names:mcpServerNamesInToml(text13),tables}}function codexMcpDisableArgs(names){return[...names].some(name=>!/^[A-Za-z0-9_-]+$/.test(name))?["-c",`mcp_servers={ ${[...names].map(name=>`${JSON.stringify(name)} = { enabled = false }`).join(", ")} }`]:[...names].flatMap(
|
|
4385
4389
|
name=>["-c",`mcp_servers.${name}.enabled=false`])}function codexConfigRunsServer(config3,name,server){let table3=config3.tables[name];if(!isRecord7(table3)||table3.enabled===!1)return!1;if("url"in server)return typeof table3.url=="string"&&address(table3.url)===address(server.url)&&isDeepStrictEqual(texts(table3.http_headers),server.headers);let args=Array.isArray(table3.args)?table3.args.map(String):[];return table3.command===server.command&&isDeepStrictEqual(args,server.args)&&isDeepStrictEqual(
|
|
4386
4390
|
texts(table3.env),server.env)}function mountedMcpServerName(name,taken){if(!taken.has(name))return name;let candidate=`${name}_openmausbot`;for(let i2=2;taken.has(candidate);i2++)candidate=`${name}_openmausbot${i2}`;return candidate}var HEADER,isRecord7,texts,address,init_codex_mcp_names=__esm({"server/drivers/codex-mcp-names.ts"(){"use strict";init_toml_lite();HEADER=/^[ \t]*\[[ \t]*mcp_servers[ \t]*\.[ \t]*(?:"((?:[^"\\]|\\.)*)"|'([^']*)'|([A-Za-z0-9_-]+))[ \t]*[.\]]/gm;isRecord7=value=>typeof value==
|
|
4387
4391
|
"object"&&value!==null&&!Array.isArray(value);texts=value=>isRecord7(value)?Object.fromEntries(Object.entries(value).map(([key2,entry])=>[key2,String(entry)])):{},address=url3=>{try{return new URL(url3).href}catch{return url3.trim()}}}});var TEAM_SESSION_MAX_MS,init_cloud_team=__esm({"server/cloud-team.ts"(){"use strict";init_user_errors();TEAM_SESSION_MAX_MS=60*6e4}});function daysMs(value,fallbackDays){let days=Number(value);return(Number.isInteger(days)&&days>=1&&days<=3650?days:fallbackDays)*24*60*6e4}var PAIRING_CODE_TTL_MS,PAIRING_CODE_MAX_TTL_MS,SESSION_TTL_MS,SESSION_MAX_AGE_MS,SESSION_RENEW_WHEN_LEFT_MS,TEAM_ACTIVE_MS,STREAM_TICKET_TTL_MS,PAIRING_LOCKOUT,scopeSchema,sessionSchema,fileSchema2,DAY_MS5,init_sessions=__esm({"server/sessions.ts"(){"use strict";init_zod();init_atomic();init_cloud_team();init_pairing_code();init_user_errors();PAIRING_CODE_TTL_MS=
|
|
@@ -4429,18 +4433,18 @@ void 0){let age=now-iat,max=validateInput("maxTokenAge option",typeof maxTokenAg
|
|
|
4429
4433
|
init_errors4()}});function isUsableJWK(jwk,entry,alg,kid){let{kty,key_ops,ext,kid:jwkKid,alg:jwkAlg,use,crv}=snapshotJwk(jwk),keyOps=Array.isArray(key_ops)?[...key_ops]:key_ops;return(ext===void 0||typeof ext=="boolean")&&(keyOps===void 0||Array.isArray(keyOps)&&keyOps.every((operation,index2)=>typeof operation=="string"&&keyOps.indexOf(operation)===index2)&&keyOps.includes("verify"))&&entry.kty.includes(kty)&&(kid===void 0||typeof kid=="string"&&kid===jwkKid)&&(jwkAlg===void 0?kty!=="AKP":alg===jwkAlg)&&(use===void 0||
|
|
4430
4434
|
use==="sig")&&(!entry.crv||crv===entry.crv)}async function importWithAlgCache(cache2,jwk,entry){let cached4=cache2.get(jwk)||cache2.set(jwk,{}).get(jwk),{alg}=entry;if(cached4[alg]===void 0){let key2=await jwkToKey(entry,{...jwk,alg,ext:!0});if(key2.type!=="public")throw new JWKSInvalid("JSON Web Key Set members must be public keys");cached4[alg]=key2}return cached4[alg]}function createLocalJWKSet(jwks){let snapshot;try{snapshot=structuredClone(jwks)}catch{}if(!isJwkSet(snapshot))throw new JWKSInvalid(
|
|
4431
4435
|
"JSON Web Key Set malformed");let cached4=new WeakMap;return Object.defineProperty(async(protectedHeader,token)=>{let{alg,kid}={...protectedHeader,...token?.header},entry=typeof alg=="string"?JWS[alg]:void 0;if(!entry||entry.secret)throw new JOSENotSupported('Unsupported "alg" value for a JSON Web Key Set');let candidates=snapshot.keys.filter(jwk2=>isUsableJWK(jwk2,entry,alg,kid)),{0:jwk,length:length2}=candidates;if(!length2)throw new JWKSNoMatchingKey;if(length2!==1){let error62=new JWKSMultipleMatchingKeys;
|
|
4432
|
-
throw error62[Symbol.asyncIterator]=async function*(){for(let jwk2 of candidates)try{yield await importWithAlgCache(cached4,jwk2,entry)}catch{}},error62}return importWithAlgCache(cached4,jwk,entry)},"jwks",{value:()=>structuredClone(snapshot)})}var init_local=__esm({"node_modules/.pnpm/jose@6.2.10/node_modules/jose/dist/webapi/jwks/local.js"(){init_jwk_to_key();init_jws_algorithms();init_errors4();init_type_checks();init_jwk_metadata()}});var init_webapi=__esm({"node_modules/.pnpm/jose@6.2.10/node_modules/jose/dist/webapi/index.js"(){init_verify();init_local()}});import{createHash as createHash20,randomBytes as randomBytes7,randomUUID as randomUUID14,timingSafeEqual as timingSafeEqual2}from"node:crypto";import{chmodSync as chmodSync8,closeSync as closeSync14,lstatSync as lstatSync6,mkdirSync as
|
|
4433
|
-
join as
|
|
4434
|
-
ntial storage must be a private directory.");chmodSync8(path3,448)}function readJson(path3){try{let stat9=lstatSync6(path3);if(!stat9.isFile()||stat9.isSymbolicLink()||stat9.size>512e3)throw new Error("Invalid credential storage.");return chmodSync8(path3,384),JSON.parse(
|
|
4435
|
-
let path3=
|
|
4436
|
+
throw error62[Symbol.asyncIterator]=async function*(){for(let jwk2 of candidates)try{yield await importWithAlgCache(cached4,jwk2,entry)}catch{}},error62}return importWithAlgCache(cached4,jwk,entry)},"jwks",{value:()=>structuredClone(snapshot)})}var init_local=__esm({"node_modules/.pnpm/jose@6.2.10/node_modules/jose/dist/webapi/jwks/local.js"(){init_jwk_to_key();init_jws_algorithms();init_errors4();init_type_checks();init_jwk_metadata()}});var init_webapi=__esm({"node_modules/.pnpm/jose@6.2.10/node_modules/jose/dist/webapi/index.js"(){init_verify();init_local()}});import{createHash as createHash20,randomBytes as randomBytes7,randomUUID as randomUUID14,timingSafeEqual as timingSafeEqual2}from"node:crypto";import{chmodSync as chmodSync8,closeSync as closeSync14,lstatSync as lstatSync6,mkdirSync as mkdirSync28,openSync as openSync13,readFileSync as readFileSync37,rmSync as rmSync21,unlinkSync as unlinkSync8,writeFileSync as writeFileSync16}from"node:fs";import{createServer as createServer8}from"node:http";import{dirname as dirname31,isAbsolute as isAbsolute16,
|
|
4437
|
+
join as join70}from"node:path";import{setTimeout as delay}from"node:timers/promises";function object2(value){if(!value||typeof value!="object"||Array.isArray(value))throw new Error("Invalid ChatGPT response.");return value}function string4(value,max=65536){return typeof value=="string"&&value.length>0&&value.length<=max}function privateDirectory(path3){if(mkdirSync28(path3,{recursive:!0,mode:448}),!lstatSync6(path3).isDirectory()||lstatSync6(path3).isSymbolicLink())throw new Error("ChatGPT crede\
|
|
4438
|
+
ntial storage must be a private directory.");chmodSync8(path3,448)}function readJson(path3){try{let stat9=lstatSync6(path3);if(!stat9.isFile()||stat9.isSymbolicLink()||stat9.size>512e3)throw new Error("Invalid credential storage.");return chmodSync8(path3,384),JSON.parse(readFileSync37(path3,"utf8"))}catch(error62){if(error62.code==="ENOENT")return null;throw new Error("ChatGPT credential storage could not be read safely. Check its permissions before signing in.")}}async function locked(directory,operation){
|
|
4439
|
+
let path3=join70(directory,".credentials.lock"),deadline=Date.now()+3e4,fd;for(;;)try{fd=openSync13(path3,"wx",384);break}catch(error62){if(error62.code!=="EEXIST")throw new Error("ChatGPT credentials could not be locked safely.");if(Date.now()>=deadline)throw new Error("ChatGPT credentials are busy. If another app process crashed, stop it and remove its abandoned credential lock before trying again.");await delay(50)}try{return writeFileSync16(fd,String(process.pid)),await operation()}finally{closeSync14(
|
|
4436
4440
|
fd),unlinkSync8(path3)}}var ISSUER,RESOURCE,DIRECT_SCOPE,SCOPES,LIFETIME,TERMINAL_REFRESH,SIGN_IN,CONSENT,ChatGptPlanAuthController,init_chatgpt_plan_auth=__esm({"server/drivers/chatgpt-plan-auth.ts"(){"use strict";init_webapi();init_atomic();ISSUER="https://auth.openai.com",RESOURCE="https://api.openai.com/v1",DIRECT_SCOPE="chatgpt.tokens.use.direct",SCOPES=`openid profile email offline_access resource.invoke ${DIRECT_SCOPE}`,LIFETIME=15*6e4,TERMINAL_REFRESH=new Set(["invalid_grant","invalid_re\
|
|
4437
4441
|
fresh_token","token_expired","refresh_token_expired","refresh_token_invalidated","refresh_token_reused"]),SIGN_IN="Continue with ChatGPT in Settings to use your ChatGPT plan.",CONSENT="ChatGPT plan usage is not enabled. Continue with ChatGPT in Settings and allow plan usage, or explicitly choose another provider.";ChatGptPlanAuthController=class{options;issuer;resource;flow=null;disposed=!1;starting=null;retryClientId=null;refusedNow=new Set;constructor(options2){if(!isAbsolute16(options2.directory))
|
|
4438
4442
|
throw new Error("ChatGPT credential storage must use an absolute path.");if(options2.testServerUrl){let url3=new URL(options2.testServerUrl);if(url3.protocol!=="http:"||url3.hostname!=="127.0.0.1"||url3.username||url3.password||url3.search||url3.hash||url3.pathname!=="/")throw new Error("ChatGPT test endpoints must be a loopback origin.");this.issuer=url3.origin,this.resource=`${url3.origin}/v1`}else this.issuer=ISSUER,this.resource=RESOURCE;this.options=options2}prepare(){privateDirectory(dirname31(
|
|
4439
|
-
this.options.directory)),privateDirectory(this.options.directory)}read(){let raw=readJson(
|
|
4443
|
+
this.options.directory)),privateDirectory(this.options.directory)}read(){let raw=readJson(join70(this.options.directory,"credentials.json"));if(raw===null)return null;let record12=object2(raw);if(!string4(record12.clientId,256)||record12.clientId==="dynamic_agent_client"||!string4(record12.subject,512)||!string4(record12.hostId,128)||record12.email!==void 0&&!string4(record12.email,320))throw new Error("Saved ChatGPT registration is invalid. Check credential storage before signing in.");if(record12.
|
|
4440
4444
|
tokens!==void 0){let tokens2=object2(record12.tokens);if(!string4(tokens2.access)||typeof tokens2.refresh!="string"||tokens2.refresh.length>65536||!string4(tokens2.id)||!Array.isArray(tokens2.scopes)||!tokens2.scopes.every(scope=>string4(scope,256))||typeof tokens2.expiresAt!="number"||!Number.isFinite(tokens2.expiresAt)||tokens2.scopes.includes(DIRECT_SCOPE)&&!tokens2.refresh||tokens2.earliestRefreshAt!==void 0&&(typeof tokens2.earliestRefreshAt!="number"||!Number.isFinite(tokens2.earliestRefreshAt)))
|
|
4441
|
-
throw new Error("Saved ChatGPT credentials are invalid. Continue with ChatGPT again.")}return record12}save(record12){writeFileAtomic(
|
|
4445
|
+
throw new Error("Saved ChatGPT credentials are invalid. Continue with ChatGPT again.")}return record12}save(record12){writeFileAtomic(join70(this.options.directory,"credentials.json"),JSON.stringify(record12),{mode:384})}refusedPath(){return join70(this.options.directory,"refused-models.json")}savedRefused(subject){let raw=readJson(this.refusedPath());if(raw===null)return[];let saved=object2(raw);return saved.subject===subject&&Array.isArray(saved.models)?saved.models.filter(slug2=>string4(slug2,
|
|
4442
4446
|
256)):[]}refusedFor(subject){let saved=[];try{saved=this.savedRefused(subject)}catch{}return[...new Set([...saved,...this.refusedNow])]}clearRefused(){this.refusedNow.clear(),rmSync21(this.refusedPath(),{force:!0})}refusedModels(){try{let subject=this.read()?.subject;return subject?this.refusedFor(subject):[]}catch{return[]}}async refuseModel(slug2){this.disposed||!string4(slug2,256)||(this.refusedNow.add(slug2),this.prepare(),await locked(this.options.directory,async()=>{let subject=this.read()?.
|
|
4443
|
-
subject,models2=subject?this.savedRefused(subject):[];subject&&!models2.includes(slug2)&&writeFileAtomic(this.refusedPath(),JSON.stringify({subject,models:[...models2,slug2]}),{mode:384})}))}async hostId(){let parent=dirname31(this.options.directory);return locked(parent,async()=>{let path3=
|
|
4447
|
+
subject,models2=subject?this.savedRefused(subject):[];subject&&!models2.includes(slug2)&&writeFileAtomic(this.refusedPath(),JSON.stringify({subject,models:[...models2,slug2]}),{mode:384})}))}async hostId(){let parent=dirname31(this.options.directory);return locked(parent,async()=>{let path3=join70(parent,"host-id.json"),saved=readJson(path3);if(saved!==null){let value2=object2(saved).hostId;if(!string4(value2)||!/^urn:uuid:[0-9a-f-]{36}$/i.test(value2))throw new Error("Saved ChatGPT host identit\
|
|
4444
4448
|
y is invalid.");return value2}let value=`urn:uuid:${randomUUID14()}`;return writeFileAtomic(path3,JSON.stringify({hostId:value}),{mode:384}),value})}async request(url3,init={}){try{let response=await fetch(url3,{...init,redirect:"error",signal:init.signal?AbortSignal.any([init.signal,AbortSignal.timeout(15e3)]):AbortSignal.timeout(15e3)});if(Number(response.headers.get("content-length"))>1048576)throw new Error("Oversized response.");let reader=response.body?.getReader(),size=0,chunks=[];if(reader)
|
|
4445
4449
|
for(;;){let{value,done}=await reader.read();if(done)break;if(size+=value.byteLength,size>1048576)throw await reader.cancel(),new Error("Oversized response.");chunks.push(value)}let text13=Buffer.concat(chunks).toString("utf8");return{response,body:text13?object2(JSON.parse(text13)):{}}}catch{throw new Error("Could not securely contact ChatGPT. Check your connection and try again; your saved account has not been removed.")}}async exchange(params,signal){return this.request(`${this.issuer}/api/acc\
|
|
4446
4450
|
ounts/oauth/token`,{method:"POST",body:params,signal})}tokenSet(body,previous2){if(!string4(body.access_token)||typeof body.token_type!="string"||body.token_type.toLowerCase()!=="bearer"||typeof body.expires_in!="number"||!Number.isFinite(body.expires_in)||body.expires_in<=0||body.expires_in>86400||body.scope!==void 0&&typeof body.scope!="string"||body.id_token!==void 0&&!string4(body.id_token))throw new Error("ChatGPT returned incomplete credentials. Continue with ChatGPT again.");let id=string4(
|
|
@@ -4468,20 +4472,20 @@ throw new Error(CONSENT);return tokens2.access})}async models(){let record12=thi
|
|
|
4468
4472
|
rmissions in ChatGPT Settings.":"ChatGPT models are unavailable right now. Try refreshing later.");if(!Array.isArray(body.models))throw new Error("ChatGPT returned an invalid model catalog. No fallback models were selected.");let options2=[];for(let entry of body.models){if(!entry||typeof entry!="object")continue;let row=entry;row.visibility!=="list"||!string4(row.slug,256)||/[\s\p{Cc}]/u.test(row.slug)||!string4(row.display_name,256)||options2.some(item=>item.id===row.slug)||refused.includes(row.
|
|
4469
4473
|
slug)||options2.push({id:row.slug,label:row.display_name})}return{default:options2[0]?.id??"",options:options2}}async signOut(){if(this.disposed)throw new Error("This provider was removed.");await this.cancel(),this.prepare(),await locked(this.options.directory,async()=>{let record12=this.read();if(!record12?.tokens)return;let revoked=!record12.tokens.refresh;try{if(!record12.tokens.refresh){delete record12.tokens,this.save(record12);return}let discovery=await this.request(`${this.issuer}/.well-\
|
|
4470
4474
|
known/openid-configuration`),endpoint=discovery.body.revocation_endpoint;if(discovery.response.ok&&discovery.body.issuer===this.issuer&&typeof endpoint=="string"&&new URL(endpoint).origin===this.issuer)for(let attempt=0;attempt<2&&!revoked;attempt++){try{let result2=await this.request(endpoint,{method:"POST",body:new URLSearchParams({token:record12.tokens.refresh,token_type_hint:"refresh_token",client_id:record12.clientId})});if(revoked=result2.response.status===200,result2.response.status<500)break}catch{}
|
|
4471
|
-
!revoked&&attempt===0&&await delay(250)}}catch{}if(delete record12.tokens,this.save(record12),this.clearRefused(),!revoked)throw Object.assign(new Error("Signed out locally, but remote revocation was not confirmed. Disconnect Limix Bot in ChatGPT Settings \u2192 Usage to end access there."),{code:"chatgpt_revocation_unconfirmed"})})}}}});import{randomBytes as randomBytes8,timingSafeEqual as timingSafeEqual3}from"node:crypto";import{mkdtempSync as mkdtempSync8,rmSync as rmSync22}from"node:fs";import{createServer as createServer9}from"node:net";import{tmpdir as tmpdir10}from"node:os";import{join as
|
|
4475
|
+
!revoked&&attempt===0&&await delay(250)}}catch{}if(delete record12.tokens,this.save(record12),this.clearRefused(),!revoked)throw Object.assign(new Error("Signed out locally, but remote revocation was not confirmed. Disconnect Limix Bot in ChatGPT Settings \u2192 Usage to end access there."),{code:"chatgpt_revocation_unconfirmed"})})}}}});import{randomBytes as randomBytes8,timingSafeEqual as timingSafeEqual3}from"node:crypto";import{mkdtempSync as mkdtempSync8,rmSync as rmSync22}from"node:fs";import{createServer as createServer9}from"node:net";import{tmpdir as tmpdir10}from"node:os";import{join as join71}from"node:path";async function startChatGptTokenBridge(accessToken){let secret2=randomBytes8(32).toString("hex"),directory=process.platform==="win32"?void 0:mkdtempSync8(join71(tmpdir10(),"omb-auth-")),path3=directory?join71(directory,
|
|
4472
4476
|
"s"):`\\\\.\\pipe\\omb-auth-${randomBytes8(16).toString("hex")}`,connections=new Set,closed=!1,server=createServer9(socket=>{connections.add(socket),socket.on("close",()=>connections.delete(socket)),socket.on("error",()=>{});let input2="";socket.setTimeout(6e4,()=>socket.destroy()),socket.on("data",chunk=>{if(input2+=chunk.toString(),input2.length>128)return socket.destroy();if(!input2.endsWith(`
|
|
4473
4477
|
`))return;socket.removeAllListeners("data");let actual=Buffer.from(input2.trim()),expected=Buffer.from(secret2);if(actual.length!==expected.length||!timingSafeEqual3(actual,expected))return socket.destroy();accessToken().then(token=>{closed||socket.end(token)},()=>socket.destroy())})});try{await new Promise((resolve35,reject)=>{server.once("error",reject),server.listen(path3,resolve35)})}catch(error62){throw directory&&rmSync22(directory,{recursive:!0,force:!0}),error62}return{env:{OMB_CODEX_AUTH_SOCKET:path3,
|
|
4474
4478
|
OMB_CODEX_AUTH_SECRET:secret2},close(){if(!closed){closed=!0;for(let socket of connections)socket.destroy();server.close(),directory&&rmSync22(directory,{recursive:!0,force:!0})}}}}var init_chatgpt_plan_token_bridge=__esm({"server/drivers/chatgpt-plan-token-bridge.ts"(){"use strict"}});function chatgptPlanCodexArgs(renewing=!1){return["-c",'model_provider="openai_chatgpt_plan"',"-c",'model_providers.openai_chatgpt_plan.name="ChatGPT plan"',"-c",'model_providers.openai_chatgpt_plan.base_url="https://api.openai.com/v1"',...renewing?["-c",`model_providers.openai_chatgpt_plan.auth.command=${JSON.stringify(process.execPath)}`,"-c",`model_providers.openai_chatgpt_plan.auth.args=[${JSON.stringify(SPAWNED_PROXIES.chatgptPlanToken)}]`,"-c","model_providers.openai_chatgpt_plan.auth.refr\
|
|
4475
4479
|
esh_interval_ms=30000","-c","model_providers.openai_chatgpt_plan.auth.timeout_ms=60000"]:["-c",'model_providers.openai_chatgpt_plan.env_key="OPENMAUSBOT_CHATGPT_TOKEN"'],"-c",'model_providers.openai_chatgpt_plan.wire_api="responses"',"-c","model_providers.openai_chatgpt_plan.requires_openai_auth=false","-c","model_providers.openai_chatgpt_plan.supports_websockets=false","-c",'cli_auth_credentials_store="ephemeral"',"-c","features.tool_search=false","-c","shell_environment_policy.ignore_default_e\
|
|
4476
4480
|
xcludes=false"]}function planTokenRenewal(readVersion){let known,pending;return{supported(){return known!==void 0?Promise.resolve(known):(pending??=readVersion().then(probe=>"version"in probe?known=renewsToken(probe.version):!1).finally(()=>{pending=void 0}),pending)},noteVersion(version2){return known=renewsToken(version2)}}}async function startPlanTokenBridge(accessToken,stillCurrent){let bridge=await startChatGptTokenBridge(async()=>{stillCurrent();let token=await accessToken();return stillCurrent(),
|
|
4477
4481
|
token});try{stillCurrent()}catch(error62){throw bridge.close(),error62}return{env:{...bridge.env,ELECTRON_RUN_AS_NODE:"1"},close:()=>bridge.close()}}var PLAN_TOKEN_BRIDGE_ENV,renewsToken,init_codex_plan_token=__esm({"server/drivers/codex-plan-token.ts"(){"use strict";init_proxy_paths();init_chatgpt_plan_token_bridge();PLAN_TOKEN_BRIDGE_ENV=["OMB_CODEX_AUTH_SOCKET","OMB_CODEX_AUTH_SECRET","ELECTRON_RUN_AS_NODE"];renewsToken=version2=>{let match=version2.match(/\b(\d+)\.(\d+)\.(\d+)\b/);return!!match&&
|
|
4478
|
-
(Number(match[1])>0||Number(match[2])>=165)}}});import{homedir as
|
|
4482
|
+
(Number(match[1])>0||Number(match[2])>=165)}}});import{homedir as homedir20}from"node:os";import{isAbsolute as isAbsolute17,join as join72,resolve as resolve23}from"node:path";function codexHome(env){if(env.CODEX_HOME)return isAbsolute17(env.CODEX_HOME)?resolve23(env.CODEX_HOME):null;let home2=userHome(env);return isAbsolute17(home2)?join72(home2,".codex"):null}async function codexAccountEmail(cli,env,timeoutMs=3e3){let cwd=env.HOME||env.USERPROFILE||homedir20();return!isAbsolute17(cwd)||!codexHome(env)?null:new Promise(resolveEmail=>{let child;
|
|
4479
4483
|
try{child=spawnCli(cli,["app-server"],{cwd,env,stdio:["pipe","pipe","pipe"]})}catch{resolveEmail(null);return}let finishing=!1,buffer="",outputBytes=0,initialized=!1,finish=async email3=>{if(finishing)return;finishing=!0,clearTimeout(timer2);let stopped=await killCliTree(child,1e3);if(!stopped&&child.pid){try{process.platform==="win32"?child.kill("SIGKILL"):process.kill(-child.pid,"SIGKILL")}catch{try{child.kill("SIGKILL")}catch{}}stopped=await killCliTree(child,1e3)}resolveEmail(stopped?email3:
|
|
4480
4484
|
null)},timer2=setTimeout(()=>{finish(null)},timeoutMs);timer2.unref();let send2=message5=>{try{child.stdin.write(`${JSON.stringify(message5)}
|
|
4481
4485
|
`)}catch{finish(null)}};child.stdin.on("error",()=>{finish(null)}),child.stderr.resume(),child.on("error",()=>{finish(null)}),child.on("close",()=>{finish(null)}),child.stdout.setEncoding("utf8"),child.stdout.on("data",chunk=>{if(finishing)return;if(outputBytes+=Buffer.byteLength(chunk),outputBytes>MAX_OUTPUT4){finish(null);return}buffer+=chunk;let newline;for(;!finishing&&(newline=buffer.indexOf(`
|
|
4482
4486
|
`))!==-1;){let line3=buffer.slice(0,newline);if(buffer=buffer.slice(newline+1),!line3.trim())continue;let message5;try{message5=JSON.parse(line3)}catch{finish(null);return}if(!initialized&&message5?.id===1){if(message5.error||!message5.result){finish(null);return}initialized=!0,send2({method:"initialized",params:{}}),send2({id:2,method:"account/read",params:{refreshToken:!1}})}else if(initialized&&message5?.id===2){let account2=message5.error?null:message5.result?.account,email3=account2?.type===
|
|
4483
|
-
"chatgpt"?account2.email:null;finish(typeof email3=="string"&&email3.length<=254&&EMAIL.test(email3)&&!/[\p{Cc}\p{Cf}]/u.test(email3)?email3:null)}}}),send2({id:1,method:"initialize",params:{clientInfo:{name:"openmausbot",version:"1"}}})})}var MAX_OUTPUT4,EMAIL,init_codex_identity=__esm({"server/drivers/codex-identity.ts"(){"use strict";init_env_path();init_procs();MAX_OUTPUT4=16384,EMAIL=/^[^\s@]+@[^\s@]+\.[^\s@]+$/}});import{readdirSync as readdirSync15,readFileSync as
|
|
4484
|
-
null}}function codexSelectedProviderArgs(env,modelId2){let provider=decodeCodexSelection(modelId2).modelProvider;return[...codexLocalProviderArgs(env,modelId2),...provider?["-c",`model_provider=${JSON.stringify(provider)}`]:[]]}function readCodexAppServerModelCatalog(cli,env,timeoutMs=8e3){return new Promise(resolve35=>{let child=spawnCli(cli,["app-server"],{cwd:
|
|
4487
|
+
"chatgpt"?account2.email:null;finish(typeof email3=="string"&&email3.length<=254&&EMAIL.test(email3)&&!/[\p{Cc}\p{Cf}]/u.test(email3)?email3:null)}}}),send2({id:1,method:"initialize",params:{clientInfo:{name:"openmausbot",version:"1"}}})})}var MAX_OUTPUT4,EMAIL,init_codex_identity=__esm({"server/drivers/codex-identity.ts"(){"use strict";init_env_path();init_procs();MAX_OUTPUT4=16384,EMAIL=/^[^\s@]+@[^\s@]+\.[^\s@]+$/}});import{readdirSync as readdirSync15,readFileSync as readFileSync38}from"node:fs";import{homedir as homedir21}from"node:os";import{basename as basename15,join as join73}from"node:path";function encodeCodexSelection(provider,model){return`${provider}${SEP}${model}`}function decodeCodexSelection(id){if(!id)return{model:null,modelProvider:null};let sep5=id.indexOf(SEP);return sep5>0?{model:id.slice(sep5+SEP.length),modelProvider:id.slice(0,sep5)}:{model:id,modelProvider:MODEL_ID2.test(id)?OFFICIAL_CODEX_PROVIDER:
|
|
4488
|
+
null}}function codexSelectedProviderArgs(env,modelId2){let provider=decodeCodexSelection(modelId2).modelProvider;return[...codexLocalProviderArgs(env,modelId2),...provider?["-c",`model_provider=${JSON.stringify(provider)}`]:[]]}function readCodexAppServerModelCatalog(cli,env,timeoutMs=8e3){return new Promise(resolve35=>{let child=spawnCli(cli,["app-server"],{cwd:homedir21(),env,stdio:["pipe","pipe","pipe"]}),settled=!1,buffer="",nextId=1,models2=[],cursors=new Set,pending=new Map,finish=catalog=>{
|
|
4485
4489
|
settled||(settled=!0,clearTimeout(timer2),killCliTree(child),resolve35(catalog))},request2=(method,params,kind)=>{let id=nextId++;pending.set(id,kind);try{child.stdin.write(`${JSON.stringify({jsonrpc:"2.0",id,method,params})}
|
|
4486
4490
|
`)}catch{finish(null)}},requestModels=cursor3=>{request2("model/list",{cursor:cursor3,limit:100},"models")},timer2=setTimeout(()=>finish(null),timeoutMs);timer2.unref?.(),child.stdout.setEncoding("utf8"),child.stdout.on("data",chunk=>{buffer+=chunk;let newline;for(;(newline=buffer.indexOf(`
|
|
4487
4491
|
`))!==-1;){let line3=buffer.slice(0,newline);if(buffer=buffer.slice(newline+1),!line3.trim())continue;let message5;try{message5=JSON.parse(line3)}catch{continue}let kind=pending.get(message5.id);if(!kind)continue;if(pending.delete(message5.id),message5.error){finish(null);return}if(kind==="initialize"){try{child.stdin.write(`${JSON.stringify({jsonrpc:"2.0",method:"initialized",params:{}})}
|
|
@@ -4489,30 +4493,30 @@ settled||(settled=!0,clearTimeout(timer2),killCliTree(child),resolve35(catalog))
|
|
|
4489
4493
|
id,label:typeof row.displayName=="string"&&row.displayName.trim()?row.displayName:row.id}),row.isDefault===!0&&(defaultModel=row.id));if(!options2.length){finish(null);return}finish({default:defaultModel&&seen.has(defaultModel)?defaultModel:options2[0].id,options:options2})}}),child.on("error",()=>finish(null)),child.on("close",()=>finish(null)),request2("initialize",{clientInfo:{name:"openmausbot",version:"1"}},"initialize")})}function unquote(raw){let value=raw.trim(),hash2=value.indexOf(" #");
|
|
4490
4494
|
if(hash2!==-1&&!(value.startsWith('"')||value.startsWith("'"))&&(value=value.slice(0,hash2).trim()),value.length>=2){let quote=value[0];if((quote==='"'||quote==="'")&&value.endsWith(quote))return value.slice(1,-1).replace(/\\"/g,'"')}return value}function parseCodexToml(text13){let result2={providers:[]},byId=new Map,section="root",providerFor=id=>{let provider=byId.get(id);return provider||(provider={id},byId.set(id,provider),result2.providers.push(provider)),provider};for(let line3 of text13.split(
|
|
4491
4495
|
/\r?\n/)){let stripped=line3.trim();if(!stripped||stripped.startsWith("#"))continue;if(stripped.startsWith("[")&&stripped.endsWith("]")){let inner=stripped.slice(1,-1),match=/^model_providers\.(.+)$/.exec(inner);if(match){let id=match[1];id.startsWith('"')&&id.endsWith('"')&&(id=id.slice(1,-1)),section=PROVIDER_ID.test(id)?providerFor(id):"other"}else section="other";continue}let eq=stripped.indexOf("=");if(eq<0)continue;let key2=stripped.slice(0,eq).trim(),value=unquote(stripped.slice(eq+1));if(value){
|
|
4492
|
-
if(section==="root"){key2==="model"&&(result2.model=value),key2==="model_provider"&&(result2.modelProvider=value);continue}section!=="other"&&(key2==="name"&&(section.name=value),key2==="base_url"&&(section.baseUrl=value),key2==="env_key"&&(section.envKey=value))}}return result2}function readText(path3){try{return
|
|
4493
|
-
name||provider}function niceLabel(model,provider,known,named2){let encoded=encodeCodexSelection(provider,model);if(named2.has(encoded))return named2.get(encoded);let host2=providerName(provider,known);return qualifiedModelLabel(model,host2,{redundantWhen:()=>host2===provider,decorate:facet=>` (${facet})`})}function collectCatalogNames(home2){let named2=new Map;for(let file2 of listDir(
|
|
4494
|
-
/-models$/,"");if(!PROVIDER_ID.test(provider))continue;let raw=readText(
|
|
4496
|
+
if(section==="root"){key2==="model"&&(result2.model=value),key2==="model_provider"&&(result2.modelProvider=value);continue}section!=="other"&&(key2==="name"&&(section.name=value),key2==="base_url"&&(section.baseUrl=value),key2==="env_key"&&(section.envKey=value))}}return result2}function readText(path3){try{return readFileSync38(path3,"utf8")}catch{return null}}function listDir(path3){try{return readdirSync15(path3)}catch{return[]}}function providerName(provider,known){return known.get(provider)?.
|
|
4497
|
+
name||provider}function niceLabel(model,provider,known,named2){let encoded=encodeCodexSelection(provider,model);if(named2.has(encoded))return named2.get(encoded);let host2=providerName(provider,known);return qualifiedModelLabel(model,host2,{redundantWhen:()=>host2===provider,decorate:facet=>` (${facet})`})}function collectCatalogNames(home2){let named2=new Map;for(let file2 of listDir(join73(home2,"model-catalogs"))){if(!file2.endsWith(".json"))continue;let provider=basename15(file2,".json").replace(
|
|
4498
|
+
/-models$/,"");if(!PROVIDER_ID.test(provider))continue;let raw=readText(join73(home2,"model-catalogs",file2));if(!raw)continue;let parsed;try{parsed=JSON.parse(raw)}catch{continue}let records2=Array.isArray(parsed)?parsed:parsed&&typeof parsed=="object"&&Array.isArray(parsed.models)?parsed.models:parsed&&typeof parsed=="object"&&Array.isArray(parsed.data)?parsed.data:[];for(let record12 of records2){if(!record12||typeof record12!="object")continue;let row=record12,slug2=typeof row.slug=="string"?
|
|
4495
4499
|
row.slug:typeof row.id=="string"?row.id:"";if(!MODEL_ID2.test(slug2))continue;let label2=typeof row.display_name=="string"?row.display_name:typeof row.name=="string"?row.name:"";label2&&named2.set(encodeCodexSelection(provider,slug2),label2)}}return named2}function idsFromModelsPayload2(payload){return(Array.isArray(payload)?payload:payload&&typeof payload=="object"&&Array.isArray(payload.data)?payload.data:payload&&typeof payload=="object"&&Array.isArray(payload.models)?payload.models:[]).flatMap(
|
|
4496
4500
|
record12=>{if(typeof record12=="string")return MODEL_ID2.test(record12)?[record12]:[];if(!record12||typeof record12!="object")return[];let id=record12.id??record12.slug;return typeof id=="string"&&MODEL_ID2.test(id)?[id]:[]})}async function probeProviderModels(provider,env,fetchImpl){if(!provider.baseUrl)return[];let url3=`${provider.baseUrl.replace(/\/$/,"")}/models`,headers={};provider.envKey&&env[provider.envKey]&&(headers.Authorization=`Bearer ${env[provider.envKey]}`);let controller=new AbortController,
|
|
4497
4501
|
timer2=setTimeout(()=>controller.abort(),1e3);timer2.unref?.();try{let response=await fetchImpl(url3,{signal:controller.signal,headers});return response.ok?idsFromModelsPayload2(await response.json()):[]}catch{return[]}finally{clearTimeout(timer2)}}async function readCodexModelCatalog(env=process.env,fetchImpl=fetch,cli){let official2=cli?await readCodexAppServerModelCatalog(cli,env):null,catalog=await catalogAround(official2??STATIC_CODEX_MODELS,env,fetchImpl);return cli&&!official2&&unconfirmedModelCatalog(
|
|
4498
|
-
catalog),catalog}async function catalogAround(official2,env,fetchImpl){let home2=codexHome(env);if(!home2)return mergeLocalInject(official2,env,fetchImpl);let mainText=readText(
|
|
4499
|
-
test(model)||provider===OFFICIAL_CODEX_PROVIDER&&official2.options.some(option=>option.id===model)||extras.push({provider,model})};remember(main2.modelProvider,main2.model);for(let file2 of listDir(home2)){if(!file2.endsWith(".config.toml"))continue;let profile=parseCodexToml(readText(
|
|
4502
|
+
catalog),catalog}async function catalogAround(official2,env,fetchImpl){let home2=codexHome(env);if(!home2)return mergeLocalInject(official2,env,fetchImpl);let mainText=readText(join73(home2,"config.toml"));if(!mainText)return mergeLocalInject(official2,env,fetchImpl);let main2=parseCodexToml(mainText),known=new Map(main2.providers.map(provider=>[provider.id,provider])),named2=collectCatalogNames(home2),extras=[],remember=(provider,model)=>{!provider||!model||!PROVIDER_ID.test(provider)||!MODEL_ID2.
|
|
4503
|
+
test(model)||provider===OFFICIAL_CODEX_PROVIDER&&official2.options.some(option=>option.id===model)||extras.push({provider,model})};remember(main2.modelProvider,main2.model);for(let file2 of listDir(home2)){if(!file2.endsWith(".config.toml"))continue;let profile=parseCodexToml(readText(join73(home2,file2))??"");for(let provider of profile.providers)known.has(provider.id)||known.set(provider.id,provider);remember(profile.modelProvider??main2.modelProvider,profile.model)}for(let[encoded,_label]of named2){
|
|
4500
4504
|
let decoded2=decodeCodexSelection(encoded);decoded2.model&&decoded2.modelProvider&&remember(decoded2.modelProvider,decoded2.model)}let live=await Promise.all([...known.values()].map(async provider=>(await probeProviderModels(provider,env,fetchImpl)).map(model=>({provider:provider.id,model}))));for(let row of live.flat())remember(row.provider,row.model);let options2=official2.options.map(option=>({...option})),seen=new Set(options2.map(option=>option.id));for(let extra of extras){let id=encodeCodexSelection(
|
|
4501
4505
|
extra.provider,extra.model);seen.has(id)||(seen.add(id),options2.push({id,label:niceLabel(extra.model,extra.provider,known,named2),custom:!0}))}let configured=main2.model&&main2.modelProvider?main2.modelProvider===OFFICIAL_CODEX_PROVIDER&&official2.options.some(option=>option.id===main2.model)?main2.model:encodeCodexSelection(main2.modelProvider,main2.model):main2.model&&seen.has(main2.model)?main2.model:null;return mergeLocalInject({default:configured&&seen.has(configured)?configured:official2.
|
|
4502
4506
|
default,options:options2},env,fetchImpl)}var STATIC_CODEX_MODELS,OFFICIAL_CODEX_PROVIDER,SEP,MODEL_ID2,PROVIDER_ID,init_codex_catalog=__esm({"server/drivers/codex-catalog.ts"(){"use strict";init_contracts();init_procs();init_codex_identity();init_startup_model_catalog();init_local_inject();STATIC_CODEX_MODELS={default:"gpt-5.6-sol",options:[{id:"gpt-6-astra",label:"GPT-6 Astra (availability unverified)"},{id:"gpt-6-sol",label:"GPT-6 Sol (availability unverified)"},{id:"gpt-6-luna",label:"GPT-6 L\
|
|
4503
|
-
una (availability unverified)"},{id:"gpt-5.6-sol",label:"GPT-5.6 Sol"},{id:"gpt-5.6-terra",label:"GPT-5.6 Terra"},{id:"gpt-5.6-luna",label:"GPT-5.6 Luna"},{id:"gpt-5.5",label:"GPT-5.5"},{id:"gpt-5.4",label:"GPT-5.4"},{id:"gpt-5.4-mini",label:"GPT-5.4 Mini"},{id:"gpt-5.3-codex-spark",label:"GPT-5.3 Codex Spark"}]},OFFICIAL_CODEX_PROVIDER="openai",SEP="::",MODEL_ID2=/^[\w][\w./:+-]*$/,PROVIDER_ID=/^[a-z][a-z0-9_-]*$/i}});import{readdirSync as readdirSync16,readFileSync as
|
|
4504
|
-
|
|
4507
|
+
una (availability unverified)"},{id:"gpt-5.6-sol",label:"GPT-5.6 Sol"},{id:"gpt-5.6-terra",label:"GPT-5.6 Terra"},{id:"gpt-5.6-luna",label:"GPT-5.6 Luna"},{id:"gpt-5.5",label:"GPT-5.5"},{id:"gpt-5.4",label:"GPT-5.4"},{id:"gpt-5.4-mini",label:"GPT-5.4 Mini"},{id:"gpt-5.3-codex-spark",label:"GPT-5.3 Codex Spark"}]},OFFICIAL_CODEX_PROVIDER="openai",SEP="::",MODEL_ID2=/^[\w][\w./:+-]*$/,PROVIDER_ID=/^[a-z][a-z0-9_-]*$/i}});import{readdirSync as readdirSync16,readFileSync as readFileSync39}from"node:fs";import{join as join74}from"node:path";function codexConfigProviderArgs(env,modelId2){let provider=decodeCodexSelection(modelId2).modelProvider,home2=codexHome(env);if(!provider||BUILT_IN.has(provider)||!BARE_KEY2.test(provider)||!home2)return[];let profiles=[];try{profiles=readdirSync16(home2).filter(file2=>file2.endsWith(".config.toml")).sort()}catch{}for(let file2 of["config.toml",...profiles]){let text13;try{text13=
|
|
4508
|
+
readFileSync39(join74(home2,file2),"utf8")}catch{continue}let entries2=providerTable(text13,provider);if(entries2.length)return overrides(env,provider,entries2)}return[]}function splitKey(text13){let parts=[],part=new RegExp(String.raw`\s*(?:([A-Za-z0-9_-]+)|"((?:[^"\\]|\\.)*)"|'([^']*)')\s*(\.|$)`,"y");for(let index2=0;index2<text13.length;){part.lastIndex=index2;let match=part.exec(text13);if(!match)return null;if(parts.push(match[1]??match[2]??match[3]??""),index2=part.lastIndex,!match[4])break}
|
|
4505
4509
|
return parts.length?parts:null}function scanValue(lines2,at2,text13){let triple=/^("""|''')/.exec(text13)?.[1];if(triple){let next=at2+1;if(!text13.slice(3).includes(triple))for(;next<lines2.length&&!lines2[next++].includes(triple););return{raw:null,next}}let raw="",depth=0,quote="";for(let index2=at2,line3=text13;;line3=lines2[index2]?.trim()??""){let end=line3.length;for(let i2=0;i2<line3.length;i2++){let char=line3[i2];if(quote)char==="\\"&"e==='"'?i2++:char===quote&&(quote="");else if(char===
|
|
4506
4510
|
'"'||char==="'")quote=char;else if(char==="["||char==="{")depth++;else if(char==="]"||char==="}")depth--;else if(char==="#"){end=i2;break}}if(raw+=`${raw?" ":""}${line3.slice(0,end).trim()}`,index2++,depth<=0||quote||index2>=lines2.length)return{raw:depth===0&&!quote&&raw?raw:null,next:index2}}}function providerTable(text13,provider){let entries2=[],lines2=text13.split(/\r?\n/),table3=[];for(let index2=0;index2<lines2.length;){let line3=lines2[index2].trim();if(!line3||line3.startsWith("#")){index2++;
|
|
4507
4511
|
continue}if(line3.startsWith("[")){let header=/^\[([^[\]]+)\]\s*(?:#.*)?$/.exec(line3);table3=header?splitKey(header[1]):null,index2++;continue}let match=KEY_LINE.exec(line3);if(!match){index2++;continue}let{raw,next}=scanValue(lines2,index2,match[2]);index2=next;let key2=splitKey(match[1]),path3=table3&&key2?[...table3,...key2]:[];raw&&path3[0]==="model_providers"&&path3[1]===provider&&entries2.push({path:path3.slice(2),raw})}return entries2}function stringValue2(raw){if(raw.startsWith("'"))return raw.
|
|
4508
4512
|
length>=2&&raw.endsWith("'")?raw.slice(1,-1):null;try{let value=JSON.parse(raw);return typeof value=="string"?value:null}catch{return null}}function overrides(env,provider,entries2){let args=[],variable=suffix=>`OPENMAUSBOT_CODEX_${provider.toUpperCase().replace(/[^A-Z0-9]+/g,"_")}_${suffix}`,set3=(key2,raw)=>args.push("-c",`model_providers.${[provider,key2].filter(Boolean).join(".")}=${raw}`),token=entries2.find(entry=>entry.path.join(".")==="experimental_bearer_token"),bearer=token?stringValue2(
|
|
4509
4513
|
token.raw):null,headers=0;for(let{path:path3,raw}of entries2){if(!path3.every(part=>BARE_KEY2.test(part))||path3[0]==="experimental_bearer_token"||bearer!==null&&path3[0]==="env_key")continue;let value=path3[0]==="http_headers"&&path3.length===2?stringValue2(raw):null;if(value===null){set3(path3.join("."),raw);continue}let name=variable(`HEADER_${++headers}`);env[name]=value,set3(`env_http_headers.${path3[1]}`,JSON.stringify(name))}return bearer!==null&&(env[variable("TOKEN")]=bearer,set3("env_k\
|
|
4510
|
-
ey",JSON.stringify(variable("TOKEN")))),args}var BUILT_IN,BARE_KEY2,KEY_PART,KEY_LINE,init_codex_config_provider=__esm({"server/drivers/codex-config-provider.ts"(){"use strict";init_codex_catalog();init_codex_identity();BUILT_IN=new Set(["openai","oss","ollama","lmstudio"]),BARE_KEY2=/^[A-Za-z0-9_-]+$/,KEY_PART=String.raw`(?:[A-Za-z0-9_-]+|"(?:[^"\\]|\\.)*"|'[^']*')`,KEY_LINE=new RegExp(String.raw`^(${KEY_PART}(?:\s*\.\s*${KEY_PART})*)\s*=\s*(.*)$`)}});import{mkdtempSync as mkdtempSync9,rmSync as rmSync23}from"node:fs";import{tmpdir as tmpdir11}from"node:os";import{join as
|
|
4514
|
+
ey",JSON.stringify(variable("TOKEN")))),args}var BUILT_IN,BARE_KEY2,KEY_PART,KEY_LINE,init_codex_config_provider=__esm({"server/drivers/codex-config-provider.ts"(){"use strict";init_codex_catalog();init_codex_identity();BUILT_IN=new Set(["openai","oss","ollama","lmstudio"]),BARE_KEY2=/^[A-Za-z0-9_-]+$/,KEY_PART=String.raw`(?:[A-Za-z0-9_-]+|"(?:[^"\\]|\\.)*"|'[^']*')`,KEY_LINE=new RegExp(String.raw`^(${KEY_PART}(?:\s*\.\s*${KEY_PART})*)\s*=\s*(.*)$`)}});import{mkdtempSync as mkdtempSync9,rmSync as rmSync23}from"node:fs";import{tmpdir as tmpdir11}from"node:os";import{join as join75}from"node:path";function codexBackgroundModel(catalog,refused=new Set,provider=OFFICIAL_CODEX_PROVIDER){let official2=provider===OFFICIAL_CODEX_PROVIDER,listed2=catalog.options.filter(option=>!(official2&&option.custom)&&!refused.has(option.id)&&decodeCodexSelection(option.id).modelProvider===provider);if(official2){for(let id of CODEX_BACKGROUND_MODELS)if(listed2.some(
|
|
4511
4515
|
option=>option.id===id))return id}return listed2.find(option=>SMALL_MODEL.test(decodeCodexSelection(option.id).model??option.id))?.id??(official2?accountDefault(catalog):null)}function accountDefault(catalog){return catalog.default||catalog.options.find(option=>!option.custom)?.id||catalog.options[0]?.id||null}function codexBackgroundRoute(catalog,smallModelsUsable,fallback,openaiUnreachable=!1){let own4=fallback?.model||accountDefault(catalog),provider=own4?providerOf(own4):OFFICIAL_CODEX_PROVIDER,
|
|
4512
4516
|
model=(smallModelsUsable&&!(openaiUnreachable&&provider===OFFICIAL_CODEX_PROVIDER)?codexBackgroundModel(catalog,fallback?.refused,provider):null)??own4;return model?own4&&own4!==model?{model,retry:own4}:{model}:null}async function runCodexBackgroundRoute(route,run6,options2={},onOpenaiUnreachable){try{return await run6(route.model)}catch(error62){let message5=error62 instanceof Error?error62.message:String(error62);if(!route.retry)throw error62;if(refusesModel(message5,route.model))options2.fallback?.
|
|
4513
4517
|
onRefused(route.model);else if(onOpenaiUnreachable&&providerOf(route.model)===OFFICIAL_CODEX_PROVIDER&&OPENAI_UNREACHABLE.test(message5))onOpenaiUnreachable();else throw error62;return run6(route.retry)}}function codexBackgroundProviderArgs(env,modelId2){let local=codexLocalProviderArgs(env,modelId2);return local.length?local:codexConfigProviderArgs(env,modelId2)}function codexBackgroundArgs(input2){return["exec","--json","--ephemeral","--skip-git-repo-check","--ignore-user-config","--sandbox","\
|
|
4514
4518
|
read-only","--cd",input2.cwd,"--model",input2.model,"-c",`model_reasoning_effort=${JSON.stringify(CODEX_BACKGROUND_EFFORT)}`,"-c",'approval_policy="never"',"-c",'web_search="disabled"',...input2.modelProvider?["-c",`model_provider=${JSON.stringify(input2.modelProvider)}`]:[],...input2.providerArgs,...codexToolSurfaceArgs(),...BACKGROUND_FEATURES_OFF.flatMap(feature=>["-c",`features.${feature}=false`]),"-"]}async function runCodexOneShot(input2){let{signal,onUsage}=input2.options??{};if(signal?.aborted)
|
|
4515
|
-
throw new Error("Codex background call aborted");let cwd=mkdtempSync9(
|
|
4519
|
+
throw new Error("Codex background call aborted");let cwd=mkdtempSync9(join75(tmpdir11(),"omb-codex-background-"));try{return await new Promise((resolve35,reject)=>{let argv=codexBackgroundArgs({model:input2.model,modelProvider:input2.modelProvider,providerArgs:input2.providerArgs,cwd}),child=input2.spawn(input2.cli,argv,{cwd,env:input2.env,stdio:["pipe","pipe","pipe"],botWork:!0}),describe3=input2.describeError??(message5=>message5.slice(0,400)),settled=!1,closed=!1,buffer="",received=0,stderr="",
|
|
4516
4520
|
answer="",failure2="",fatal="",usage2,completed=!1,finish=async error62=>{if(!settled){if(settled=!0,clearTimeout(timer2),signal?.removeEventListener("abort",abort),closed||await input2.kill(child).catch(()=>{}),!error62&&usage2)try{onUsage?.(usage2)}catch{error62=new Error("Codex background usage callback failed")}error62?reject(error62):answer.trim()?resolve35(answer.trim()):reject(new Error("Codex background call returned no text"))}},abort=()=>{finish(new Error("Codex background call aborted"))},
|
|
4517
4521
|
timer2=setTimeout(()=>{finish(new Error(`Codex background call timed out${fatal?`: ${describe3(fatal)}`:""}`))},input2.timeoutMs??input2.options?.timeoutMs??CODEX_BACKGROUND_TIMEOUT_MS);timer2.unref?.();let onEvent=event=>{let type2=event?.type;if(type2==="item.started"||type2==="item.updated"||type2==="item.completed"){let item=event.item??{};if(!QUIET_ITEMS.has(item.type)){finish(new Error(`Codex background call tried to use a tool (${String(item.type??"unknown")})`));return}type2==="item.comp\
|
|
4518
4522
|
leted"&&item.type==="agent_message"&&typeof item.text=="string"&&(answer=item.text,answer.length>CODEX_BACKGROUND_MAX_CHARS&&finish(new Error("Codex background answer exceeded its limit")));return}if(type2==="turn.completed"){completed=!0;let reported=event.usage??{},count5=value=>typeof value=="number"&&Number.isFinite(value)&&value>=0?value:void 0;usage2={model:input2.model,input:count5(reported.input_tokens),output:count5(reported.output_tokens),...count5(reported.cached_input_tokens)!==void 0?
|
|
@@ -4523,25 +4527,25 @@ new Error(`Codex background call failed: ${describe3(failure2||fatal)}`));if(!co
|
|
|
4523
4527
|
`).filter(Boolean).at(-1);return void finish(new Error(`Codex background call exited ${code??"on a signal"}${said?`: ${describe3(said)}`:""}`))}finish()}}),signal?.addEventListener("abort",abort,{once:!0}),child.stdin.on("error",()=>{}),child.stdin.end(input2.prompt)})}finally{try{rmSync23(cwd,{recursive:!0,force:!0,maxRetries:5,retryDelay:100})}catch{}}}var CODEX_BACKGROUND_TIMEOUT_MS,CODEX_BACKGROUND_MAX_CHARS,MAX_STDOUT_BYTES,CODEX_BACKGROUND_MODELS,CODEX_BACKGROUND_EFFORT,SMALL_MODEL,providerOf,
|
|
4524
4528
|
OPENAI_UNREACHABLE,BACKGROUND_FEATURES_OFF,QUIET_ITEMS,init_codex_background_text=__esm({"server/drivers/codex-background-text.ts"(){"use strict";init_quick_model_fallback();init_codex_catalog();init_codex_config_provider();init_codex_tool_surface();init_local_inject();CODEX_BACKGROUND_TIMEOUT_MS=12e4,CODEX_BACKGROUND_MAX_CHARS=2e5,MAX_STDOUT_BYTES=4e6,CODEX_BACKGROUND_MODELS=["gpt-6-luna","gpt-5.6-luna","gpt-5.4-mini"],CODEX_BACKGROUND_EFFORT="low",SMALL_MODEL=/(?:^|[-.])(?:luna|mini|nano)(?:$|[-.])/i,
|
|
4525
4529
|
providerOf=id=>decodeCodexSelection(id).modelProvider??OFFICIAL_CODEX_PROVIDER;OPENAI_UNREACHABLE=/country, region,? or territory|unsupported_country|\b403\b|forbidden|error sending request|connection refused|dns error|failed to lookup address|network is unreachable/i;BACKGROUND_FEATURES_OFF=["shell_tool","unified_exec","shell_snapshot","view_image","image_generation","apps","plugins","remote_plugin","multi_agent","hooks","memories","goals","skill_mcp_dependency_install","tool_suggest","sleep_to\
|
|
4526
|
-
ol","daemon_auto_start"];QUIET_ITEMS=new Set(["agent_message","reasoning","todo_list","error"])}});import{createHash as createHash21}from"node:crypto";import{mkdirSync as
|
|
4530
|
+
ol","daemon_auto_start"];QUIET_ITEMS=new Set(["agent_message","reasoning","todo_list","error"])}});import{createHash as createHash21}from"node:crypto";import{mkdirSync as mkdirSync29,readFileSync as readFileSync40}from"node:fs";import{join as join76}from"node:path";function parseReceipt(raw){if(!raw)return null;let trimmed=raw.trim();if(isFingerprint(trimmed))return{instructions:trimmed};try{let parsed=JSON.parse(trimmed);if(parsed&&typeof parsed=="object"&&!Array.isArray(parsed)){let record12=parsed;if(typeof record12.instructions=="string"&&isFingerprint(record12.instructions))return{instructions:record12.
|
|
4527
4531
|
instructions,...typeof record12.volatile=="string"&&isFingerprint(record12.volatile)?{volatile:record12.volatile}:{}}}}catch{}return null}function codexDeveloperInstructions(config3,botInstructions){if(!config3||typeof config3!="object"||Array.isArray(config3))throw new Error("Codex returned no effective configuration; cannot safely update bot instructions.");let configured=config3.developer_instructions;if(configured!=null&&typeof configured!="string")throw new Error("Codex returned invalid dev\
|
|
4528
4532
|
eloper instructions; cannot safely update bot instructions.");return configured?`${botInstructions||"No Limix Bot bot-specific instructions remain."}
|
|
4529
4533
|
|
|
4530
|
-
${configured}`:botInstructions}async function syncCodexInstructions(key2,nativeThreadId,instructions,volatile,resumed,request2,mentionTurn=!1){let directory=
|
|
4534
|
+
${configured}`:botInstructions}async function syncCodexInstructions(key2,nativeThreadId,instructions,volatile,resumed,request2,mentionTurn=!1){let directory=join76(DATA_DIR,"codex-instructions"),path3=join76(directory,`${digest2(JSON.stringify([key2,nativeThreadId]))}.sha256`),fingerprint4=digest2(instructions),volatileFingerprint=digest2(volatile),previous2;try{previous2=parseReceipt(readFileSync40(path3,"utf8"))}catch(error62){if(error62.code!=="ENOENT")throw error62;previous2=null}if(resumed&&
|
|
4531
4535
|
previous2?.instructions!==fingerprint4)try{await request2("thread/inject_items",{threadId:nativeThreadId,items:[{type:"message",role:"developer",content:[{type:"input_text",text:`The following replaces the previous developer instruction block supplied by Limix Bot, including its native configured rules and bot-specific instructions. Other Codex instructions and permissions still apply.
|
|
4532
4536
|
|
|
4533
4537
|
`+(instructions||"No Limix Bot bot-specific instructions remain.")}]}]})}catch(error62){throw error62 instanceof Error&&/method not found|unknown method/i.test(error62.message)?new Error(`This Codex version cannot update bot instructions in a resumed session. Update Codex and retry: ${error62.message}`,{cause:error62}):error62}let deliverVolatile=!resumed||previous2?.volatile!==volatileFingerprint||mentionTurn,hadVolatile=typeof previous2?.volatile=="string"&&previous2.volatile!==digest2("");(!resumed||
|
|
4534
|
-
previous2?.instructions!==fingerprint4)&&(
|
|
4535
|
-
{"server/drivers/codex-instructions.ts"(){"use strict";init_config3();init_atomic();digest2=value=>createHash21("sha256").update(value).digest("hex"),isFingerprint=value=>/^[0-9a-f]{64}$/.test(value)}});import{readFileSync as
|
|
4538
|
+
previous2?.instructions!==fingerprint4)&&(mkdirSync29(directory,{recursive:!0}),writeFileAtomic(path3,JSON.stringify({instructions:fingerprint4}),{mode:384}));let commitVolatile=previous2?.instructions===fingerprint4&&previous2?.volatile===volatileFingerprint?null:()=>{mkdirSync29(directory,{recursive:!0}),writeFileAtomic(path3,JSON.stringify({instructions:fingerprint4,volatile:volatileFingerprint}),{mode:384})};return{deliverVolatile,hadVolatile,commitVolatile}}var digest2,isFingerprint,init_codex_instructions=__esm(
|
|
4539
|
+
{"server/drivers/codex-instructions.ts"(){"use strict";init_config3();init_atomic();digest2=value=>createHash21("sha256").update(value).digest("hex"),isFingerprint=value=>/^[0-9a-f]{64}$/.test(value)}});import{readFileSync as readFileSync41}from"node:fs";import{join as join77}from"node:path";function storedCodexLogin(env){let home2=codexHome(env);if(!home2)return null;try{return readFileSync41(join77(home2,"auth.json"),"utf8")}catch{return null}}function codexReportsLogin(said){return/^(?:logged in|api key configured)\b/im.test(said)}function codexLoginStatus(cli,env){return new Promise(resolve35=>execCli(cli,["login","status"],{timeout:8e3,env},(err,stdout2,stderr)=>{let said=`${stdout2}
|
|
4536
4540
|
${stderr??""}`;resolve35(!err&&codexReportsLogin(said)?"signed-in":err&&/^(?:not logged in|error checking login status)\b/im.test(said)?"signed-out":"unknown")}))}function codexLoginCheck(cli){let confirmedWithout,forgets=0;return{check:async env=>{let stored=storedCodexLogin(env);if(readable(stored)||stored===confirmedWithout)return"present";let forgetsBefore=forgets,status2=await codexLoginStatus(cli,env);return status2==="signed-in"&&forgets===forgetsBefore&&(confirmedWithout=stored),status2===
|
|
4537
4541
|
"signed-out"&&!readable(storedCodexLogin(env))?"missing":"present"},forget:()=>{forgets+=1,confirmedWithout=void 0}}}var readable,init_codex_login=__esm({"server/drivers/codex-login.ts"(){"use strict";init_procs();init_codex_identity();readable=stored=>{if(stored===null)return!1;try{return JSON.parse(stored),!0}catch{return!1}}}});function loginFailure(output2){return/(unexpected argument|unrecognized (argument|option)|unknown option).*device-auth/i.test(output2)?"This server's Codex CLI needs updating for browser sign-in. Run npm install -g @openai/codex@latest on the server, then try again.":/device.{0,40}(disabled|not enabled|not allowed)|enable.{0,40}device/i.test(output2)?"Enable device-code login in your ChatGPT security settings or ask your workspace admin to allow it, then try again.":/expired|expiration|timed out/i.
|
|
4538
4542
|
test(output2)?"The ChatGPT sign-in code expired. Start sign-in again for a new code.":"ChatGPT sign-in did not finish. Check the server's connection and that device-code login is enabled in ChatGPT, then try again."}var CODEX_DEVICE_SIGN_IN,CodexDeviceAuthController,init_codex_device_auth=__esm({"server/drivers/codex-device-auth.ts"(){"use strict";init_device_sign_in();init_device_auth();init_codex_login();CODEX_DEVICE_SIGN_IN={provider:"codex",product:"Codex",account:"ChatGPT",homeEnv:"CODEX_HO\
|
|
4539
4543
|
ME",homeDir:".codex",loginArgs:["login","--device-auth"],install:"Run npm install -g @openai/codex@latest on the server, then try again.",failure:loginFailure,status:{args:["login","status"],read:(code,output2)=>code===0&&/^logged in.*chatgpt\b/im.test(output2)?"signed-in":code===0&&codexReportsLogin(output2)?"other":code!==0&&/^not logged in\b/im.test(output2)?"signed-out":"unknown"},logoutArgs:["logout"]},CodexDeviceAuthController=class extends DeviceAuthController{constructor(options2){super(
|
|
4540
|
-
CODEX_DEVICE_SIGN_IN,options2)}}}});import{lstatSync as lstatSync7,mkdirSync as
|
|
4544
|
+
CODEX_DEVICE_SIGN_IN,options2)}}}});import{lstatSync as lstatSync7,mkdirSync as mkdirSync30,readdirSync as readdirSync17,realpathSync as realpathSync10,rmSync as rmSync24,statSync as statSync19,symlinkSync,unlinkSync as unlinkSync9}from"node:fs";import{isAbsolute as isAbsolute18,join as join78,relative as relative8,resolve as resolve24}from"node:path";function note(path3,message5){noted.has(path3)||(noted.add(path3),console.error(`codex: ${message5}`))}function inside2(parent,child){let path3=relative8(parent,child);return path3===
|
|
4541
4545
|
""||!path3.startsWith("..")&&!isAbsolute18(path3)}function givesWay(path3,name){if(!lstatSync7(path3).isDirectory())return RUNTIME_LOCKS.has(name);let names=readdirSync17(path3);return RUNTIME_LOCKS.has(name)?!names.some(entry=>entry.endsWith(".lock")&&entry!==".coordination.lock"):names.every(entry=>REBUILT.has(entry))}function linkEntry(target2,link2,name){let stats;try{stats=lstatSync7(link2)}catch{stats=null}if(stats?.isSymbolicLink()){try{if(realpathSync10(link2)===realpathSync10(target2))return!0}catch{}
|
|
4542
|
-
unlinkSync9(link2)}else if(stats){if(!givesWay(link2,name))return!1;rmSync24(link2,{recursive:!0,force:!0})}let folder=statSync19(target2).isDirectory();try{symlinkSync(target2,link2,process.platform==="win32"?folder?"junction":"file":void 0)}catch(error62){if(error62.code!=="EEXIST")throw error62}return!0}function linkSharedCodexHome(sharedHome,planHome){if(
|
|
4543
|
-
own4=resolve24(planHome);if(inside2(shared,own4)||inside2(own4,shared))return;let names;try{for(let name of SHARED_FOLDERS)
|
|
4544
|
-
if(!(PRIVATE2.has(name)||LOCAL.has(name)||SQLITE_JOURNAL.test(name)))try{linkEntry(
|
|
4546
|
+
unlinkSync9(link2)}else if(stats){if(!givesWay(link2,name))return!1;rmSync24(link2,{recursive:!0,force:!0})}let folder=statSync19(target2).isDirectory();try{symlinkSync(target2,link2,process.platform==="win32"?folder?"junction":"file":void 0)}catch(error62){if(error62.code!=="EEXIST")throw error62}return!0}function linkSharedCodexHome(sharedHome,planHome){if(mkdirSync30(planHome,{recursive:!0,mode:448}),!sharedHome||!isAbsolute18(sharedHome)||!isAbsolute18(planHome))return;let shared=resolve24(sharedHome),
|
|
4547
|
+
own4=resolve24(planHome);if(inside2(shared,own4)||inside2(own4,shared))return;let names;try{for(let name of SHARED_FOLDERS)mkdirSync30(join78(shared,name),{recursive:!0,mode:448});names=readdirSync17(shared)}catch(error62){return note(shared,`could not share your Codex home with the ChatGPT plan: ${error62.message}`)}for(let name of PRIVATE2){let path3=join78(own4,name);try{lstatSync7(path3).isSymbolicLink()&&unlinkSync9(path3)}catch{}}let kept=[];for(let name of new Set([...SHARED_FOLDERS,...names]))
|
|
4548
|
+
if(!(PRIVATE2.has(name)||LOCAL.has(name)||SQLITE_JOURNAL.test(name)))try{linkEntry(join78(shared,name),join78(own4,name),name)||kept.push(name)}catch(error62){note(join78(own4,name),`could not link ${JSON.stringify(name)} of your Codex home for the ChatGPT plan: ${error62.message}`)}kept.length&¬e(own4,`the ChatGPT plan's Codex home keeps its own ${kept.join(", ")} from earlier turns; the rest of your Codex home is shared`)}var SHARED_FOLDERS,PRIVATE2,LOCAL,RUNTIME_LOCKS,REBUILT,SQLITE_JOURNAL,
|
|
4545
4549
|
noted,init_codex_shared_home=__esm({"server/drivers/codex-shared-home.ts"(){"use strict";SHARED_FOLDERS=["sessions","archived_sessions","sqlite","shell_snapshots","worktrees","skills","plugins","cache","logs","mcp-oauth-locks","thread-writer-locks"],PRIVATE2=new Set(["auth.json","auth.lock","models_cache.json"]),LOCAL=new Set(["log","memories","tmp",".DS_Store"]),RUNTIME_LOCKS=new Set(["mcp-oauth-locks","thread-writer-locks",".sqlite-maintenance.lock"]),REBUILT=new Set([".system",".DS_Store"]),SQLITE_JOURNAL=
|
|
4546
4550
|
/-(?:wal|shm|journal)$/,noted=new Set}});function boundedLabel(value){if(typeof value!="string")return null;let label2=value.trim();return label2&&label2.length<=160&&!containsControlCharacter(label2)?label2:null}function mcpElicitationDeclined(value){let server=boundedLabel(value);return server?noticeFailure("chat.notice.codexElicitationDeclined",{server}):noticeFailure("chat.notice.codexElicitationDeclinedGeneric")}function mcpAppApprovalText(form){return form?.summaryCode?{summaryCode:form.summaryCode,...form.summaryParams?{summaryParams:form.
|
|
4547
4551
|
summaryParams}:{}}:{}}function ordinaryApprovalValue(value){let normalized=value.trim().toLowerCase();return/session|always|permanent|forever|persistent/.test(normalized)?!1:normalized==="once"||/^(?:accept|approve|allow)(?:ed|[-_]?once)?$/.test(normalized)}function mcpAppApprovalForm(params){let request2=plainRecord2(params);if(!request2||request2.mode!=="form")return null;let metadata=plainRecord2(request2._meta),target2=plainRecord2(metadata?.target),toolParams=plainRecord2(metadata?.tool_params),
|
|
@@ -4565,10 +4569,10 @@ item);return next2!==item&&(changed2=!0),next2},next=Array.isArray(value)?value.
|
|
|
4565
4569
|
vailable"):(emit({type:"request.resolved",requestId,behavior:"answer",source:"user"}),"answered"):"unavailable");let choices=questionChoices(questions);emit({type:"request.opened",requestId,requestType:"question",tool:"ask_user",summary:askQuestionSummary(questions),questions,...choices?{choices}:{}})}function codexQuestionReply(behavior,message5,source,questions){let mapped2=behavior==="answer"&&source==="user"&&typeof message5=="string"?questionAnswersById(message5,questions):{},answers=Object.
|
|
4566
4570
|
create(null);for(let[id,answer]of Object.entries(mapped2))answers[id]={answers:[answer]};return{answers}}var init_codex_questions=__esm({"server/drivers/codex-questions.ts"(){"use strict";init_ask_question();init_contracts()}});function parseCodexReleaseVersion(value){let match=/^(?:.*\bcodex-cli\s+)?v?(\d+)\.(\d+)\.(\d+)(-[0-9a-z.-]+)?(?:\+[0-9a-z.-]+)?$/i.exec(value.trim());return match?{parts:match.slice(1,4).map(Number),prerelease:!!match[4]}:null}function codexVersionBehind(installed,latest){let a2=parseCodexReleaseVersion(installed),b3=parseCodexReleaseVersion(latest);if(!a2||!b3||b3.prerelease)return!1;for(let i2=0;i2<3;i2++)if(a2.parts[i2]!==b3.parts[i2])return a2.parts[i2]<b3.parts[i2];return a2.prerelease}function createCodexReleaseReader(fetchImpl=fetch,now=Date.
|
|
4567
4571
|
now){let cached4,expires=0;return()=>(cached4&&now()<expires||(expires=now()+3600*1e3,cached4=(async()=>{try{let response=await fetchImpl("https://registry.npmjs.org/@openai/codex/latest",{signal:AbortSignal.timeout(3e3),headers:{Accept:"application/json"}});if(!response.ok)throw new Error("Release lookup failed");let payload=await response.json(),version2=typeof payload.version=="string"?payload.version:"",parsed=parseCodexReleaseVersion(version2);if(!parsed||parsed.prerelease)throw new Error("\
|
|
4568
|
-
Invalid stable release");return version2}catch{return expires=now()+300*1e3,null}})()),cached4)}var readLatestCodexRelease,init_codex_release=__esm({"server/drivers/codex-release.ts"(){"use strict";readLatestCodexRelease=createCodexReleaseReader()}});import{existsSync as
|
|
4572
|
+
Invalid stable release");return version2}catch{return expires=now()+300*1e3,null}})()),cached4)}var readLatestCodexRelease,init_codex_release=__esm({"server/drivers/codex-release.ts"(){"use strict";readLatestCodexRelease=createCodexReleaseReader()}});import{existsSync as existsSync30}from"node:fs";function codexUpdateCommand(cli,platform=process.platform){if(cli==="codex")return"codex update";let trimmed=cli.trim(),tokens2=trimmed.includes(" ")&&existsSync30(trimmed)?[trimmed]:splitCliString(trimmed),quote=platform==="win32"?token=>`'${token.replaceAll("'","''")}'`:token=>`'${token.replaceAll("'","'\\''")}'`,command=(tokens2.length>0?tokens2:[trimmed]).map(quote).join(" ");return platform==="win32"?`& ${command} update`:`${command} update`}async function codexReleaseUpdate(version2,cli){
|
|
4569
4573
|
let latest=await readLatestCodexRelease();if(!(!latest||!codexVersionBehind(version2,latest)))return{title:`Update Codex to ${latest}`,message:`A newer stable Codex CLI is available (installed: ${version2}). Update it, then refresh models. Model availability also depends on your signed-in account.`,command:codexUpdateCommand(cli)}}var init_codex_update=__esm({"server/drivers/codex-update.ts"(){"use strict";init_env_path();init_codex_release()}});function effectiveApprovalPolicy(value){if(value==="untrusted"||value==="on-request"||value==="never")return value;let granular=plainRecord3(plainRecord3(value)?.granular);return granular&&typeof granular.mcp_elicitations=="boolean"&&typeof granular.rules=="boolean"&&typeof granular.sandbox_approval=="boolean"&&(granular.request_permissions===void 0||typeof granular.request_permissions=="boolean")&&(granular.skill_approval===void 0||typeof granular.skill_approval=="boolean")?{granular:{mcp_elicitations:granular.
|
|
4570
4574
|
mcp_elicitations,rules:granular.rules,sandbox_approval:granular.sandbox_approval,...typeof granular.request_permissions=="boolean"?{request_permissions:granular.request_permissions}:{},...typeof granular.skill_approval=="boolean"?{skill_approval:granular.skill_approval}:{}}}:"on-request"}function effectiveApprovalsReviewer(value){return value==="auto_review"||value==="guardian_subagent"?value:"user"}var plainRecord3,init_codex_approval_config=__esm({"server/drivers/codex-approval-config.ts"(){"u\
|
|
4571
|
-
se strict";plainRecord3=value=>value&&typeof value=="object"&&!Array.isArray(value)?value:null}});var init_agents_tool_limit=__esm({"server/drivers/agents-tool-limit.ts"(){"use strict"}});import{createHash as createHash23}from"node:crypto";import{mkdirSync as
|
|
4575
|
+
se strict";plainRecord3=value=>value&&typeof value=="object"&&!Array.isArray(value)?value:null}});var init_agents_tool_limit=__esm({"server/drivers/agents-tool-limit.ts"(){"use strict"}});import{createHash as createHash23}from"node:crypto";import{mkdirSync as mkdirSync31}from"node:fs";import{join as join79}from"node:path";import{homedir as homedir22}from"node:os";function decodeConfig2(raw){let o=raw??{};if(o.authMode!==void 0&&o.authMode!=="chatgpt-plan")throw new Error("Unknown Codex sign-in mode.");if(o.authMode&&o.managed)throw new Error("ChatGPT plan and Company billing cannot be combined.");if(o.endpoint&&(o.authMode||o.managed))throw new Error("Direct API, ChatGPT plan and\
|
|
4572
4576
|
Company billing cannot be combined.");return{cli:typeof o.cli=="string"?o.cli:"codex",fullAuto:o.fullAuto===!0,...o.authMode==="chatgpt-plan"?{authMode:"chatgpt-plan"}:{},...o.endpoint?{endpoint:decodeRoutedCodexConfig(o.endpoint,"Direct API")}:{},...o.managed&&typeof o.managed=="object"?{managed:decodeRoutedCodexConfig(o.managed)}:{}}}function noteRenamedMcpServer(name,mountName){renamedMcpServers.has(name)||(renamedMcpServers.add(name),console.error(`codex: MCP server ${JSON.stringify(name)} \
|
|
4573
4577
|
is mounted as ${JSON.stringify(mountName)} for this bot to keep its CLI configuration distinct`))}function grantedPermissions(raw){return!raw||typeof raw!="object"||Array.isArray(raw)?{}:Object.fromEntries(Object.entries(raw).filter(([,value])=>value!=null))}function additionalPermissionSummary(permissions,reason){let requested=grantedPermissions(permissions),exact=JSON.stringify(requested);return`${typeof reason=="string"&&reason.trim()?`${reason.trim()} \u2014 `:""}Requested permissions: ${exact}`}
|
|
4574
4578
|
function extendShellExclusions(policy,patterns){let unconfirmed2=()=>new Error("Codex could not confirm its shell environment exclusions. No prompt was sent."),exclude=policy.exclude??void 0,filters=policy.filters??void 0;if(exclude!==void 0&&(!Array.isArray(exclude)||exclude.some(name=>typeof name!="string")))throw unconfirmed2();if(filters===void 0)return{"shell_environment_policy.exclude":[...new Set([...exclude??[],...patterns])]};let table3=plainRecord2(filters);if(!table3||Object.values(table3).
|
|
@@ -4586,8 +4590,8 @@ init_codex_mcp_startup();init_codex_mcp_mount();init_codex_unsupported_calls();i
|
|
|
4586
4590
|
init_codex_instructions();init_prompt_split();init_codex_device_auth();init_codex_identity();init_codex_shared_home();init_codex_app_approval();init_codex_errors();init_codex_login();init_key_rejections();init_resume_recovery();init_mcp_tool_images();init_codex_images();init_ask_question();init_codex_questions();init_codex_update();init_codex_approval_config();init_agents_tool_limit();init_harness_budget();init_tool_scope();init_tool_scope_support();init_mcp_gate_config();init_own_apps();init_mcp_directory();
|
|
4587
4591
|
init_tool_progress();init_codex_catalog();DRIVER_KIND2="codex";PRIVATE_ENV_FAMILIES=["OMB_GATE_CONFIG_","OMB_REMOTE_MCP_CONFIG_"],PROXY_LITERAL_ENV=["NODE_USE_ENV_PROXY","NO_PROXY","no_proxy"],SHELL_ESSENTIALS=new Set(["PATH","HOME","USER","LOGNAME","SHELL","TMPDIR","TERM","LANG","TZ"]),DENY_TIMEOUT_NOTE2="Limix Bot: nobody answered this permission request in time. Skip this action and finish what you can without it.",renamedMcpServers=new Set;CodexDriver={driverKind:DRIVER_KIND2,metadata:{displayName:"\
|
|
4588
4592
|
Codex",supportsMultipleInstances:!0},install:{command:{darwin:"npm install -g @openai/codex",linux:"npm install -g @openai/codex",win32:"npm install -g @openai/codex"},needsNode:!0,docsUrl:"https://github.com/openai/codex",signInCommand:"codex login"},models:STATIC_CODEX_MODELS,decodeConfig:decodeConfig2,defaultConfig:()=>decodeConfig2({}),async create(input2){let{instanceId,config:config3}=input2,routed=config3.endpoint??config3.managed,routedProvider=config3.endpoint?"openmaus_endpoint":"openm\
|
|
4589
|
-
aus_company",plan=config3.authMode==="chatgpt-plan",planUnavailable=plan&&(hostedWorkspaceConfigured()||cloudHomeConfigured())?"ChatGPT plan sign-in for hosted Pro requires OpenAI's hosted-app approval. Use a Company model or API key until that integration is approved; the local desktop flow cannot be used here.":void 0,planDirectory=
|
|
4590
|
-
NPM_CONFIG_LOGLEVEL:"error"};delete env.OPENAI_API_KEY,stripWorkspaceCredentialEnv(env),delete env.OPENMAUSBOT_CHATGPT_TOKEN,delete env.OPENMAUSBOT_CODEX_API_KEY;for(let name of PLAN_TOKEN_BRIDGE_ENV)delete env[name];return config3.endpoint&&(env.OPENMAUSBOT_CODEX_API_KEY=input2.environment.OPENMAUSBOT_CODEX_API_KEY,env.CODEX_HOME=input2.environment.CODEX_HOME),plan&&(env.CODEX_HOME=
|
|
4593
|
+
aus_company",plan=config3.authMode==="chatgpt-plan",planUnavailable=plan&&(hostedWorkspaceConfigured()||cloudHomeConfigured())?"ChatGPT plan sign-in for hosted Pro requires OpenAI's hosted-app approval. Use a Company model or API key until that integration is approved; the local desktop flow cannot be used here.":void 0,planDirectory=join79(DATA_DIR,"providers","chatgpt-plan",createHash23("sha256").update(instanceId).digest("hex")),childEnv=()=>{let env={...process.env,...input2.environment,PATH:augmentedPath(),
|
|
4594
|
+
NPM_CONFIG_LOGLEVEL:"error"};delete env.OPENAI_API_KEY,stripWorkspaceCredentialEnv(env),delete env.OPENMAUSBOT_CHATGPT_TOKEN,delete env.OPENMAUSBOT_CODEX_API_KEY;for(let name of PLAN_TOKEN_BRIDGE_ENV)delete env[name];return config3.endpoint&&(env.OPENMAUSBOT_CODEX_API_KEY=input2.environment.OPENMAUSBOT_CODEX_API_KEY,env.CODEX_HOME=input2.environment.CODEX_HOME),plan&&(env.CODEX_HOME=join79(planDirectory,"codex")),env},catalogEnv=childEnv(),planAuth=plan?new ChatGptPlanAuthController({directory:planDirectory}):
|
|
4591
4595
|
null,planRenewal=planTokenRenewal(()=>readCliVersion(catalogEnv)),planGeneration=0,planSigningOut=!1,disposed=!1,planWarning,models2=plan?{default:"",options:[]}:routed?{default:routed.models[0],options:routed.models.map(id=>({id,label:id,...config3.endpoint?{custom:!0}:{}}))}:STATIC_CODEX_MODELS,refreshModels=async(preserveExisting=!1)=>{if(!routed){if(planAuth){let generation=planGeneration,kept=preserveExisting&&models2.options.length>0?models2:null;kept||(models2={default:"",options:[]});try{
|
|
4592
4596
|
if(!planUnavailable&&!planSigningOut&&!disposed){let catalog=await planAuth.models();generation===planGeneration&&!planSigningOut&&!disposed&&(!kept||catalog.options.length)&&(models2=catalog)}}catch(error62){if(!kept)throw error62;unconfirmedModelCatalog(kept)}}else try{let resolved2=await readCodexModelCatalog(catalogEnv,fetch,config3.cli);resolved2.options.length?models2=resolved2:unconfirmedModelCatalog(models2)}catch{unconfirmedModelCatalog(models2)}try{writeStartupModelCache(instanceId,models2)}catch{}}},
|
|
4593
4597
|
hidePlanRefusedModel=(model,raw,route)=>{if(!planAuth||!model||!codexPlanModelRefused(raw,route))return;let options2=models2.options.filter(option=>option.id!==model);models2={default:models2.default===model?options2[0]?.id??"":models2.default,options:options2},planAuth.refuseModel(model).then(()=>refreshModels(!0)).catch(()=>{})},modelsCliVersion=null,startupModelRefresh=null;routed?await refreshModels():startupModelRefresh=(await openStartupModelCatalog({instanceId,use:catalog=>{models2=catalog},
|
|
@@ -4595,8 +4599,8 @@ current:()=>models2,refresh:async()=>{if(planAuth)try{await refreshModels(laterS
|
|
|
4595
4599
|
return[`codex-login:${home2}`,stored]},smallModelsUsable=()=>!plan&&loginMark()===null,loginRefused=()=>{let mark=loginMark();mark&¬eKeyRejected(...mark)},loginAccepted=(mark=loginMark())=>{mark&¬eKeyAccepted(...mark)},loginRejected=()=>{let mark=loginMark();return mark!==null&&keyRejected(...mark)},authentication=new CodexDeviceAuthController({cli:config3.cli,environment:childEnv,signInRejected:loginRejected,onAuthenticated:async()=>{loginAccepted(),await refreshModels()}}),listeners2=new Set,
|
|
4596
4600
|
active=new Map,emit=event=>{for(let l of Array.from(listeners2))l(event)},base2=(threadId,turnId)=>({eventId:newEventId(),provider:DRIVER_KIND2,threadId,turnId,createdAt:new Date().toISOString()}),sendTurn=async turn=>{startupModelRefresh&&await startupModelRefresh,turn={...turn,toolScope:assertToolScopeSupported(DRIVER_KIND2,turn.toolScope)};let generation=planGeneration,assertPlanCurrent=()=>{if(disposed)throw new Error("This provider was removed. Select a connected account and send again.");if(planAuth&&
|
|
4597
4601
|
(planSigningOut||generation!==planGeneration))throw new Error("The ChatGPT account changed while this message was preparing. Select a connected account and send again.")};if(assertPlanCurrent(),planUnavailable)throw new Error(planUnavailable);let planToken=planAuth?await planAuth.accessToken():void 0;if(assertPlanCurrent(),planAuth){let refused=planAuth.refusedModels();if(turn.model&&refused.includes(turn.model)){models2.options.length||(await refreshModels(),assertPlanCurrent());let usable=models2.
|
|
4598
|
-
options.find(option=>!refused.includes(option.id));usable&&(turn={...turn,model:usable.id})}if((!turn.model||!models2.options.some(model=>model.id===turn.model))&&(await refreshModels(),assertPlanCurrent(),!turn.model||!models2.options.some(model=>model.id===turn.model)))throw new Error("This model is not available to the selected ChatGPT plan. Refresh models and choose a listed model; API billing will not be used.");linkSharedCodexHome(codexHome({...process.env,...input2.environment}),
|
|
4599
|
-
"codex"))}if(config3.endpoint){if(!turn.model||!config3.endpoint.models.includes(turn.model))throw new Error("Select a model configured for this direct API endpoint.");if(!input2.environment.OPENMAUSBOT_CODEX_API_KEY||!input2.environment.CODEX_HOME)throw new Error("Direct API key or isolated Codex home is missing. Edit the endpoint in Settings.");
|
|
4602
|
+
options.find(option=>!refused.includes(option.id));usable&&(turn={...turn,model:usable.id})}if((!turn.model||!models2.options.some(model=>model.id===turn.model))&&(await refreshModels(),assertPlanCurrent(),!turn.model||!models2.options.some(model=>model.id===turn.model)))throw new Error("This model is not available to the selected ChatGPT plan. Refresh models and choose a listed model; API billing will not be used.");linkSharedCodexHome(codexHome({...process.env,...input2.environment}),join79(planDirectory,
|
|
4603
|
+
"codex"))}if(config3.endpoint){if(!turn.model||!config3.endpoint.models.includes(turn.model))throw new Error("Select a model configured for this direct API endpoint.");if(!input2.environment.OPENMAUSBOT_CODEX_API_KEY||!input2.environment.CODEX_HOME)throw new Error("Direct API key or isolated Codex home is missing. Edit the endpoint in Settings.");mkdirSync31(input2.environment.CODEX_HOME,{recursive:!0,mode:448})}if(config3.managed){if(!turn.model)throw new Error("Company model access is unavaila\
|
|
4600
4604
|
ble: no model is selected. Reconnect your organization; personal billing will not be used.");if(!config3.managed.models.includes(turn.model))throw new Error("Company model access is unavailable: "+turn.model+" is not approved for your organization. Reconnect your organization; personal billing will not be used.");if(!input2.environment.OPENMAUSBOT_COMPANY_API_KEY)throw new Error("Company model access is unavailable: OPENMAUSBOT_COMPANY_API_KEY is missing. Reconnect your organization; personal bi\
|
|
4601
4605
|
lling will not be used.");if(!input2.environment.CODEX_HOME)throw new Error("Company model access is unavailable: CODEX_HOME is missing. Reconnect your organization; personal billing will not be used.")}let stopRequested=!1,promptSubmitted=!1,recoveredMissingSession=!1,loginRaceRetried=!1,stopSignal=new AbortController,{threadId}=turn,approvalMode=turn.approvalMode??(config3.fullAuto?"full":"ask");turn=perTurnCustomMcp(turn);let autoAcceptPermissions=approvalMode==="full",chatgptTurn=ownLogin&&decodeCodexSelection(
|
|
4602
4606
|
turn.model||models2.default).modelProvider===OFFICIAL_CODEX_PROVIDER,route=plan?"plan":chatgptTurn?"own":"other",hideRefusedModel=raw=>hidePlanRefusedModel(turn.model,raw,route),signedOut=chatgptTurn&&await loginCheck.check(childEnv())==="missing",authBridge=planAuth&&await planRenewal.supported()?await startPlanTokenBridge(()=>planAuth.accessToken(),()=>{if(assertPlanCurrent(),stopRequested)throw new Error("This task has ended.")}):null;try{if(assertPlanCurrent(),active.has(threadId))throw new Error(
|
|
@@ -4613,7 +4617,7 @@ integrations?.phone?["openmausbot_phone"]:[]]);for(let[name,server]of Object.ent
|
|
|
4613
4617
|
toolScope!==void 0)mountSelected("phone","openmausbot_phone",turn.integrations.phone);else{let bridge=turn.integrations.phone;Object.assign(env,bridge.env);for(let name of Object.keys(bridge.env))mountedNames.add(name);let prefix="mcp_servers.openmausbot_phone";directMounts.push("openmausbot_phone"),appServerArgs.push("-c",`${prefix}.command=${JSON.stringify(bridge.command)}`,"-c",`${prefix}.args=${JSON.stringify(bridge.args)}`,"-c",`${prefix}.env_vars=${JSON.stringify(Object.keys(bridge.env))}`,
|
|
4614
4618
|
"-c",`${prefix}.default_tools_approval_mode="auto"`)}let customBox=customServerEnvBox(turn.integrations?.custom,selectedMcp),boxAdmitted=boxAdmittedEnv(customBox),mountedEnv=[...mountedNames].filter(name=>env[name]!==void 0&&!SHELL_ESSENTIALS.has(name)&&!name.startsWith("LC_")&&(name==="ELECTRON_RUN_AS_NODE"||boxAdmitted.has(name)||baseEnv.get(name)!==env[name])),privateEnv=[...new Set([...config3.endpoint?["OPENMAUSBOT_CODEX_API_KEY"]:[],...turn.toolScope!==void 0?["OMB_GATE_CONFIG_*"]:[],...PRIVATE_ENV_FAMILIES.
|
|
4615
4619
|
filter(family2=>mountedEnv.some(name=>name.startsWith(family2))).map(family2=>`${family2}*`),...mountedEnv.filter(name=>!PRIVATE_ENV_FAMILIES.some(family2=>name.startsWith(family2))).sort()])],provenPrivateEnv=turn.toolScope!==void 0||directoryMounts.size>0;privateEnv.length&&turn.toolScope===void 0&&appServerArgs.push("-c","features.shell_snapshot=false");let selectionConfig=turn.toolScope===void 0?{}:{config:{mcp_servers:Object.fromEntries([...selectedMcp].map(([name,server])=>[name,{command:server.
|
|
4616
|
-
command,args:server.args,env_vars:Object.keys(server.env),env:{},default_tools_approval_mode:selectedApprovals.get(name)??"prompt"}]))}},commandCwd=permissionLaunchCwd(turn.cwd??
|
|
4620
|
+
command,args:server.args,env_vars:Object.keys(server.env),env:{},default_tools_approval_mode:selectedApprovals.get(name)??"prompt"}]))}},commandCwd=permissionLaunchCwd(turn.cwd??homedir22()),releaseSlot=tryCodexLaunchSlot()??await waitForLaunchSlot(attempt);if(!releaseSlot)return;let child=spawnHoldingSlot(releaseSlot,()=>spawnCli(...codexLaunch(config3.cli,appServerArgs),{cwd:turn.cwd??homedir22(),env,stdio:["pipe","pipe","pipe"],...customBox},"bot")),abandoned=!1,codexThreadId=null,codexTurnId=null,
|
|
4617
4621
|
startingNativeTurn=!1,earlyNotifications=[],mcpStartup=mcpStartupTracker(child),state={settled:!1,lastError:"",lastErrorSetup:!1,retryError:"",authRecovery:!1,lastText:"",sawStreamDelta:!1,streamed:!1,usage:void 0,usageBaseline:void 0},asks=new Map,nextId=1,sensitiveResponseIds=new Set,rpcPending=new Map,send2=obj=>{try{child.stdin.write(JSON.stringify(obj)+`
|
|
4618
4622
|
`)}catch{}appendNative(threadId,{dir:"out",source:"codex.app-server",msg:codexNativeLogMessage(obj)})},request2=(method,params,timeoutMs=codexRpcTimeoutMs(method))=>new Promise((resolve35,reject)=>{let id=nextId++;method==="config/read"&&sensitiveResponseIds.add(id);let timer2=setTimeout(()=>{rpcPending.delete(id)&&reject(new Error(`codex ${method} timed out after ${timeoutMs}ms`))},timeoutMs);typeof timer2.unref=="function"&&timer2.unref(),rpcPending.set(id,{resolve:v3=>{if(clearTimeout(timer2),
|
|
4619
4623
|
method==="thread/start"||method==="thread/resume"){let returnedId=v3?.thread?.id,requestedId=method==="thread/resume"&¶ms&&typeof params=="object"&&"threadId"in params?params.threadId:null;typeof returnedId=="string"&&returnedId?codexThreadId=returnedId:typeof requestedId=="string"&&requestedId&&(codexThreadId=requestedId)}if(method==="turn/start"){if(typeof v3?.turn?.id!="string"||!v3.turn.id){reject(new Error("Codex did not return a native turn id"));return}codexTurnId=v3.turn.id,startingNativeTurn=
|
|
@@ -4651,10 +4655,10 @@ outputTokens??0,...typeof last.cachedInputTokens=="number"?{cachedInput:last.cac
|
|
|
4651
4655
|
message:message5,...text13?{text:text13}:{}})),settle2(t2.status==="completed",t2.status==="completed"?null:classifyError({text:state.lastError}).reason==="provider_safety"?"provider_safety":state.lastError||t2.status||"failed");break}case"error":{let error62=p3.error&&typeof p3.error=="object"?p3.error:{message:p3.message};if(!error62.message)break;if(p3.willRetry===!0){state.retryError=String(error62.message);break}turnError(error62);break}case"modelProvider/authRecoveryStarted":state.authRecovery=
|
|
4652
4656
|
!0;break;case"modelProvider/authRecoveryCompleted":state.authRecovery=!1;break}},buf="";child.stdout.setEncoding("utf8"),child.stdout.on("data",chunk=>{if(abandoned||state.settled)return;buf+=chunk;let nl;for(;!state.settled&&!abandoned&&(nl=buf.indexOf(`
|
|
4653
4657
|
`))!==-1;){let line3=buf.slice(0,nl);if(buf=buf.slice(nl+1),!line3.trim())continue;let msg;try{msg=JSON.parse(line3)}catch{continue}stderrSinceOutput="";let loggedMessage=codexNativeIncomingLogMessage(msg,sensitiveResponseIds);if(appendNative(threadId,{dir:"in",source:"codex.app-server",msg:loggedMessage}),msg.id!==void 0&&(msg.result!==void 0||msg.error!==void 0)){let pend=rpcPending.get(msg.id);pend&&(rpcPending.delete(msg.id),msg.error?pend.reject(new CodexRpcError(msg.error)):pend.resolve(msg.
|
|
4654
|
-
result))}else msg.id!==void 0&&msg.method?handleServerRequest(msg):msg.method&&handleNotification(msg)}});let stderr="",stderrSinceOutput="";child.stderr.on("data",c2=>{stderr+=c2,stderrSinceOutput+=c2,stderr.length>8192&&(stderr=stderr.slice(-8192)),stderrSinceOutput.length>2048&&(stderrSinceOutput=stderrSinceOutput.slice(-2048))}),child.on("error",e=>{abandoned||(emit({...base2(threadId,turnId),type:"runtime.error",...describeSpawnFailure(e,config3.cli,turn.cwd??
|
|
4658
|
+
result))}else msg.id!==void 0&&msg.method?handleServerRequest(msg):msg.method&&handleNotification(msg)}});let stderr="",stderrSinceOutput="";child.stderr.on("data",c2=>{stderr+=c2,stderrSinceOutput+=c2,stderr.length>8192&&(stderr=stderr.slice(-8192)),stderrSinceOutput.length>2048&&(stderrSinceOutput=stderrSinceOutput.slice(-2048))}),child.on("error",e=>{abandoned||(emit({...base2(threadId,turnId),type:"runtime.error",...describeSpawnFailure(e,config3.cli,turn.cwd??homedir22())}),settle2(!1,"spaw\
|
|
4655
4659
|
n_error"))}),child.on("close",(code,signal)=>{if(abandoned)return;if(state.settled){stop();return}if(stopRequested){settle2(!1,"interrupted");return}let recentStderr=stderrSinceOutput.trim(),hadStreamedOutput=codexTurnId!==null||state.sawStreamDelta,verdict=signal!==null?{transient:!1,reason:"interrupted"}:classifyError({exitCode:code,stderr:recentStderr}),exitMessage=`codex exited ${code}${signal?` (signal ${signal})`:""} before turn/completed${recentStderr?`: ${recentStderr.slice(-300)}`:hadStreamedOutput&&
|
|
4656
4660
|
stderr.trim()?"; no stderr after the last app-server output":""}`;if(!stopRequested&&codexTurnId===null&&earlyNotifications.length===0&&verdict.transient&&attempt<RETRY_MAX_ATTEMPTS-1){relaunch(verdict.reason,exitMessage,"exit_before_result").catch(()=>{});return}emit({...base2(threadId,turnId),type:"runtime.error",message:exitMessage}),settle2(!1,"exit_before_result")}),active.set(threadId,{stop,turnId,asks,steer:steerActiveTurn,pid:child.pid}),attempt===0&&!announced&&emit({...base2(threadId,turnId),
|
|
4657
|
-
type:"turn.started"});try{let initialized=await request2("initialize",{clientInfo:{name:"openmausbot",title:"Limix Bot",version:serverVersion()},capabilities:{experimentalApi:!0}});send2({jsonrpc:"2.0",method:"initialized",params:{}});let effectiveConfig;try{effectiveConfig=(await request2("config/read",{cwd:turn.cwd??
|
|
4661
|
+
type:"turn.started"});try{let initialized=await request2("initialize",{clientInfo:{name:"openmausbot",title:"Limix Bot",version:serverVersion()},capabilities:{experimentalApi:!0}});send2({jsonrpc:"2.0",method:"initialized",params:{}});let effectiveConfig;try{effectiveConfig=(await request2("config/read",{cwd:turn.cwd??homedir22(),includeLayers:!1}))?.config}catch(error62){let invalid2=error62 instanceof CodexRpcError&&/^invalid configuration\b/i.test(error62.message);throw new Error(invalid2?"Co\
|
|
4658
4662
|
dex rejected its configuration as invalid. Check ~/.codex/config.toml (or CODEX_HOME) for a broken entry, then retry.":"Could not read Codex configuration; cannot safely update bot instructions. Retry after checking Codex.")}if(privateEnv.length||authBridge){let snapshot2=effectiveConfig?.features?.shell_snapshot;if(provenPrivateEnv||authBridge?snapshot2!==!1:snapshot2===!0)throw new Error("Codex could not disable inherited shell snapshots. No prompt was sent.")}if(privateEnv.length||plan){let rawPolicy=effectiveConfig?.
|
|
4659
4663
|
shell_environment_policy;if(rawPolicy!==void 0&&(!rawPolicy||typeof rawPolicy!="object"||Array.isArray(rawPolicy)))throw new Error("Codex could not confirm its shell environment policy. No prompt was sent.");selectionConfig.config={...selectionConfig.config,...extendShellExclusions(rawPolicy??{},[...plan?["OPENMAUSBOT_CHATGPT_TOKEN"]:[],...authBridge?PLAN_TOKEN_BRIDGE_ENV:[],...privateEnv])}}if(turn.toolScope!==void 0){let catalog=effectiveConfig?.mcp_servers;if(!catalog||typeof catalog!="object"||
|
|
4660
4664
|
Array.isArray(catalog))throw new Error("Codex could not confirm its selected MCP configuration. No prompt was sent.");for(let[name,entry]of Object.entries(catalog)){if(entry&&typeof entry=="object"&&entry.enabled===!1)continue;let expected=selectedMcp.get(name),actual=entry;if(!expected||actual?.command!==expected.command||JSON.stringify(actual?.args??[])!==JSON.stringify(expected.args??[])||!Array.isArray(actual?.env_vars)||JSON.stringify([...actual.env_vars].sort())!==JSON.stringify(Object.keys(
|
|
@@ -4664,7 +4668,7 @@ approvalMode==="custom"?approvalParams=customApprovalParams(effectiveConfig):app
|
|
|
4664
4668
|
text;if(cursor3){let resumeThread=()=>request2("thread/resume",{...selectionConfig,threadId:cursor3,developerInstructions,model:selection.model,...selection.modelProvider?{modelProvider:selection.modelProvider}:{},...approvalParams.thread}),resumeUnarchived=()=>resumeThread().catch(error62=>archivedNativeCodexThread(error62,cursor3)?request2("thread/unarchive",{threadId:cursor3}).then(resumeThread,()=>Promise.reject(error62)):Promise.reject(error62));try{let resumed;try{resumed=await resumeUnarchived()}catch(error62){
|
|
4665
4669
|
if(!approvalParams.fallback||!permissionProfileUnsupported(error62))throw error62;approvalParams=approvalParams.fallback,resumed=await resumeUnarchived()}approvalParams=withResolvedSandbox(approvalParams,resumed),codexThreadId=resumed?.thread?.id??cursor3,rolloutAt=rolloutMark(resumed?.thread?.path),resumedNativeThread=!0}catch(error62){let failure2=classifyResumeFailure({attempted:!0,rejected:error62 instanceof CodexRpcError,promptSubmitted,producedOutput:state.sawStreamDelta});if(recoveredMissingSession||
|
|
4666
4670
|
stopRequested||state.settled||!turn.recoveryText?.trim()||!(missingNativeCodexThread(error62,cursor3)||archivedNativeCodexThread(error62,cursor3)||codexProviderMismatch(error62))||!mayReplay(failure2))throw error62;recoveredMissingSession=!0;let rebuild=recoveryPromptFor({recoveryText:turn.recoveryText,currentText:turn.text,failure:failure2});rebuiltFromReplay=rebuild.replayed,promptText=rebuild.text}}if(!codexThreadId){let startThread=()=>request2("thread/start",{...selectionConfig,developerInstructions,
|
|
4667
|
-
cwd:turn.cwd??
|
|
4671
|
+
cwd:turn.cwd??homedir22(),model:selection.model,...selection.modelProvider?{modelProvider:selection.modelProvider}:{},...approvalParams.thread,...turn.guestConfined?{environments:[]}:{},ephemeral:!1}),started;try{started=await startThread()}catch(error62){if(!approvalParams.fallback||!permissionProfileUnsupported(error62))throw error62;approvalParams=approvalParams.fallback,started=await startThread()}approvalParams=withResolvedSandbox(approvalParams,started),codexThreadId=started?.thread?.id??null,
|
|
4668
4672
|
rolloutAt=rolloutMark(started?.thread?.path),startedModel=started?.model??null}if(!codexThreadId)throw new Error("Codex did not return a native thread id");let{deliverVolatile,hadVolatile,commitVolatile}=await syncCodexInstructions(threadId,codexThreadId,developerInstructions,promptSplit?turn.systemVolatile??"":"",resumedNativeThread,request2,!!turn.mentionTurn);deliverVolatile&&(promptText=withContextNote(volatileContextNote(promptSplit?turn.systemVolatile??"":"",hadVolatile),promptText)),emit(
|
|
4669
4673
|
{...base2(threadId,turnId),type:"session.started",sessionId:codexThreadId,model:startedModel??turn.model??null,...rebuiltFromReplay?{rebuilt:!0}:{}}),rebuiltFromReplay&&emit({...base2(threadId,turnId),type:"runtime.notice",message:rebuiltSessionNotice("Codex")});let turnInput=[...promptText?[{type:"text",text:promptText}]:[],...await codexImageInputs(turn.images)],startTurn=()=>(promptSubmitted=!0,startingNativeTurn=!0,request2("turn/start",{threadId:codexThreadId,input:turnInput,...approvalParams.
|
|
4670
4674
|
turn,...turn.guestConfined?{environments:[]}:{},...turn.effort?{effort:turn.effort}:{}})),waitNames=supportsMcpStartup(initialized?.userAgent)?enabledMcpMounts([...selectedMcp.keys(),...directMounts],effectiveConfig,turn.toolScope!==void 0):[];if(!await mcpStartup.settled(waitNames,stopSignal.signal)||stopRequested||state.settled)return releaseSlot();try{await startTurn()}catch(error62){if(!approvalParams.fallback||!permissionProfileUnsupported(error62))throw error62;approvalParams=approvalParams.
|
|
@@ -4675,8 +4679,8 @@ authenticationUnavailableReason:planUnavailable};let env=childEnv(),probe=await
|
|
|
4675
4679
|
snapshot(),update:await codexReleaseUpdate(version2,config3.cli),...warning?{warning:{title:"Check ChatGPT connection",message:warning}}:{}};if(config3.endpoint)return{state:"available",version:version2,authenticated:!!(input2.environment.OPENMAUSBOT_CODEX_API_KEY&&input2.environment.CODEX_HOME),billing:"metered"};if(config3.managed)return{state:"available",version:version2,authenticated:!!(input2.environment.OPENMAUSBOT_COMPANY_API_KEY&&input2.environment.CODEX_HOME),billing:"metered"};let previousCliVersion=modelsCliVersion;
|
|
4676
4680
|
modelsCliVersion=version2,previousCliVersion!==null&&previousCliVersion!==version2&&await refreshModels();let authenticated=await codexLoginStatus(config3.cli,env)==="signed-in";if(authenticated&&loginRejected())return{state:"available",version:version2,authenticated:!1,reason:CODEX_SIGN_IN_EXPIRED,update:await codexReleaseUpdate(version2,config3.cli),billing:"subscription"};let email3=authenticated?await codexAccountEmail(config3.cli,env):null;return{state:"available",version:version2,authenticated,
|
|
4677
4681
|
...email3?{account:{email:email3}}:{},update:await codexReleaseUpdate(version2,config3.cli),billing:"subscription"}},openaiUnreachable=!1,generateMemoryText=async(prompt,options2={})=>{if(startupModelRefresh&&await startupModelRefresh,disposed)throw new Error("This provider was removed.");if(planUnavailable)throw new Error(planUnavailable);let env=childEnv(),providerArgs=[],authBridge=null;if(planAuth){if(planSigningOut)throw new Error("This ChatGPT account is being disconnected.");let generation=planGeneration,
|
|
4678
|
-
stillCurrent=()=>{if(planSigningOut||disposed||generation!==planGeneration)throw new Error("This ChatGPT account changed.")};models2.options.length||await refreshModels();let token=await planAuth.accessToken();stillCurrent(),linkSharedCodexHome(codexHome({...process.env,...input2.environment}),
|
|
4679
|
-
env??{OPENMAUSBOT_CHATGPT_TOKEN:token}),providerArgs=chatgptPlanCodexArgs(!!authBridge)}else if(config3.endpoint){if(!input2.environment.OPENMAUSBOT_CODEX_API_KEY||!input2.environment.CODEX_HOME)throw new Error("Direct API key or isolated Codex home is missing. Edit the endpoint in Settings.");
|
|
4682
|
+
stillCurrent=()=>{if(planSigningOut||disposed||generation!==planGeneration)throw new Error("This ChatGPT account changed.")};models2.options.length||await refreshModels();let token=await planAuth.accessToken();stillCurrent(),linkSharedCodexHome(codexHome({...process.env,...input2.environment}),join79(planDirectory,"codex"));let renewing=await planRenewal.supported();stillCurrent(),authBridge=renewing?await startPlanTokenBridge(()=>planAuth.accessToken(),stillCurrent):null,Object.assign(env,authBridge?.
|
|
4683
|
+
env??{OPENMAUSBOT_CHATGPT_TOKEN:token}),providerArgs=chatgptPlanCodexArgs(!!authBridge)}else if(config3.endpoint){if(!input2.environment.OPENMAUSBOT_CODEX_API_KEY||!input2.environment.CODEX_HOME)throw new Error("Direct API key or isolated Codex home is missing. Edit the endpoint in Settings.");mkdirSync31(input2.environment.CODEX_HOME,{recursive:!0,mode:448}),providerArgs=endpointCodexArgs(config3.endpoint)}else if(config3.managed){if(!input2.environment.OPENMAUSBOT_COMPANY_API_KEY||!input2.environment.
|
|
4680
4684
|
CODEX_HOME)throw new Error("Company model access is unavailable. Reconnect your organization; personal billing will not be used.");providerArgs=managedCodexArgs(config3.managed)}let route=codexBackgroundRoute(models2,smallModelsUsable(),options2.fallback,openaiUnreachable);if(!route)throw authBridge?.close(),new Error("Codex lists no model for background calls. Refresh models in Settings \u2192 Model providers \u2192 Codex.");try{return await runCodexBackgroundRoute(route,id=>{let selection=planAuth||
|
|
4681
4685
|
routed?{model:id,modelProvider:null}:decodeCodexSelection(id);return runCodexOneShot({spawn:spawnCli,kill:killCliTree,cli:config3.cli,env,prompt,options:options2,model:selection.model??id,modelProvider:selection.modelProvider,providerArgs:planAuth||routed?providerArgs:codexBackgroundProviderArgs(env,id),describeError:message5=>{let route2=planAuth?"plan":selection.modelProvider===OFFICIAL_CODEX_PROVIDER?"own":"other";return hidePlanRefusedModel(selection.model??id,message5,route2),codexUserError(
|
|
4682
4686
|
message5,route2)}})},options2,planAuth||config3.managed?void 0:()=>{openaiUnreachable=!0})}finally{authBridge?.close()}};return{instanceId,driverKind:DRIVER_KIND2,displayName:input2.displayName,enabled:input2.enabled,get models(){return models2},quickModelsUsable:smallModelsUsable,refreshModels,...startupModelRefresh?{startupModelRefresh}:{},generateMemoryText,...plan?{authenticationMethod:"browser-pkce"}:{},...config3.endpoint?{}:{startAuthentication:async()=>{if(planUnavailable)throw new Error(
|
|
@@ -4946,11 +4950,11 @@ type==="text"?splitText(child,source):(visit4(child),[child])}))};visit4(tree)}v
|
|
|
4946
4950
|
raw`(?<![\w.~/\\:@-])\/(?:${POSIX_PART}+\/)+${POSIX_PART}*[\w@+~-]${EXT}(?![\w/\\])`,String.raw`(?<![\w\\/])[A-Za-z]:\\(?:${WIN_PART}+\\)*${WIN_PART}*[^\s\\/:*?"<>|\x60()\[\].]${EXT}(?![\w\\])`,String.raw`(?<![\w\\])\\\\${WIN_PART}+(?:\\${WIN_PART}+)+${EXT}(?![\w\\])`].join("|"),"g"),CODE_PATH=/^(?:\/(?:[^\s/][^/]*\/)+[^/]+|[A-Za-z]:\\(?:[^\\]+\\?)+|\\\\[^\\]+(?:\\[^\\]+)+)$/,unescape=raw=>raw.replace(/\\([!-/:-@[-`{-~])/g,"$1"),isPosix=raw=>raw.startsWith("/")}});var init_secret_folder=__esm({"server/secret-folder.ts"(){"use strict"}});function walkMarkdown(node3,visit4){let pending=[node3];for(;pending.length>0;){let current=pending.pop();visit4(current);let children=current.children??[];for(let index2=children.length-1;index2>=0;index2-=1)pending.push(children[index2])}}function renderedMarkdownTargets(markdown,plainPaths=!1){let definitions=new Map,links=[],references=[],tree=fromMarkdown(markdown,{mdastExtensions:[windowsPathDestinations]});plainPaths&&linkPlainPaths(tree,markdown),walkMarkdown(tree,node3=>{node3.type==="d\
|
|
4947
4951
|
efinition"&&node3.identifier&&node3.url?definitions.has(node3.identifier)||definitions.set(node3.identifier,node3.url):(node3.type==="link"||node3.type==="image")&&node3.url?links.push(node3.url):(node3.type==="linkReference"||node3.type==="imageReference")&&node3.identifier&&references.push(node3.identifier)});for(let identifier of references){let target2=definitions.get(identifier);target2&&links.push(target2)}return links}function messageFileTargets(text13){return[...new Set(renderedMarkdownTargets(
|
|
4948
4952
|
text13))].filter(target2=>!target2.startsWith("#")&&!target2.startsWith("//")&&(/^[a-z]:[\\/]/i.test(target2)||/^file:/i.test(target2)||!/^[a-z][a-z\d+.-]*:/i.test(target2)))}var MESSAGE_FILE_MAX_BYTES,MESSAGE_FILE_DOWNLOAD_MAX_BYTES,init_message_file=__esm({"server/message-file.ts"(){"use strict";init_mdast_util_from_markdown();init_markdown_windows_paths();init_markdown_plain_paths();init_upload_limits();init_secret_folder();init_user_errors();MESSAGE_FILE_MAX_BYTES=26214400,MESSAGE_FILE_DOWNLOAD_MAX_BYTES=
|
|
4949
|
-
500*1024*1024}});import{readFileSync as
|
|
4953
|
+
500*1024*1024}});import{readFileSync as readFileSync42,statSync as statSync20}from"node:fs";function chatImageBudget(){let used=0;return parts=>{if(!Array.isArray(parts))return;let added=parts.reduce((total,part)=>total+(part.type==="image_url"?part.image_url.url.length:0),0);if(used+added>CHAT_IMAGE_BUDGET)throw new Error("Turn image budget exceeded (32 MiB encoded); screenshot cannot be retained. An operation may already have taken effect; inspect its state before retrying.");used+=added}}function assertImageTransport(url3){
|
|
4950
4954
|
let endpoint=new URL(url3),loopback=endpoint.hostname==="localhost"||endpoint.hostname==="[::1]"||/^127(?:\.\d{1,3}){3}$/.test(endpoint.hostname);if(endpoint.protocol!=="https:"&&!(endpoint.protocol==="http:"&&loopback))throw new Error("Images and computer tools require HTTPS for remote API endpoints; HTTP is supported only on loopback.")}function chatImage(item){let{mimeType,data}=item;if(typeof mimeType!="string"||!MIME.has(mimeType)||typeof data!="string"||!data.length||data.length>Math.ceil(
|
|
4951
4955
|
IMAGE_BYTES/3)*4||data.length%4||!/^[A-Za-z0-9+/]*={0,2}$/.test(data))throw new Error("Invalid or oversized MCP image");let bytes2=Buffer.from(data,"base64"),matches2=mimeType==="image/png"?bytes2.length>=33&&bytes2.subarray(0,8).equals(Buffer.from("89504e470d0a1a0a","hex"))&&bytes2.toString("ascii",12,16)==="IHDR":mimeType==="image/jpeg"?bytes2.length>=4&&bytes2[0]===255&&bytes2[1]===216&&bytes2[2]===255:mimeType==="image/gif"?bytes2.length>=13&&["GIF87a","GIF89a"].includes(bytes2.toString("asc\
|
|
4952
4956
|
ii",0,6)):bytes2.length>=16&&bytes2.toString("ascii",0,4)==="RIFF"&&bytes2.toString("ascii",8,12)==="WEBP";if(bytes2.length>IMAGE_BYTES||bytes2.toString("base64")!==data||!matches2)throw new Error("Image bytes do not match the declared MIME type");return{type:"image_url",image_url:{url:`data:${mimeType};base64,${data}`}}}function chatUserContent(turn){if(!turn.images?.length)return turn.text;let budget=chatImageBudget();return[{type:"text",text:turn.text},...turn.images.map(image=>{if(statSync20(
|
|
4953
|
-
image.path).size>IMAGE_BYTES)throw new Error("Image exceeds 20 MB");let part=chatImage({mimeType:image.mime,data:
|
|
4957
|
+
image.path).size>IMAGE_BYTES)throw new Error("Image exceeds 20 MB");let part=chatImage({mimeType:image.mime,data:readFileSync42(image.path).toString("base64")});return budget([part]),part})]}function chatToolImages(callId,images){return images?.length?[{type:"text",text:`Screenshot result from tool call ${callId}:`},...images]:[]}var IMAGE_BYTES,MIME,CHAT_IMAGE_BUDGET,init_chat_images=__esm({"server/drivers/chat-images.ts"(){"use strict";IMAGE_BYTES=20*1024*1024,MIME=new Set(["image/png","image/\
|
|
4954
4958
|
jpeg","image/webp","image/gif"]),CHAT_IMAGE_BUDGET=32*1024*1024}});var require_code=__commonJS({"node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/code.js"(exports){"use strict";Object.defineProperty(exports,"__esModule",{value:!0});exports.regexpCode=exports.getEsmExportName=exports.getProperty=exports.safeStringify=exports.stringify=exports.strConcat=exports.addCodeArg=exports.str=exports._=exports.nil=exports._Code=exports.Name=exports.IDENTIFIER=exports._CodeOrName=void 0;var _CodeOrName=class{};exports._CodeOrName=_CodeOrName;exports.IDENTIFIER=
|
|
4955
4959
|
/^[a-z$_][a-z$_0-9]*$/i;var Name=class extends _CodeOrName{constructor(s4){if(super(),!exports.IDENTIFIER.test(s4))throw new Error("CodeGen: name must be a valid identifier");this.str=s4}toString(){return this.str}emptyStr(){return!1}get names(){return{[this.str]:1}}};exports.Name=Name;var _Code=class extends _CodeOrName{constructor(code){super(),this._items=typeof code=="string"?[code]:code}toString(){return this.str}emptyStr(){if(this._items.length>1)return!1;let item=this._items[0];return item===
|
|
4956
4960
|
""||item==='""'}get str(){var _a4;return(_a4=this._str)!==null&&_a4!==void 0?_a4:this._str=this._items.reduce((s4,c2)=>`${s4}${c2}`,"")}get names(){var _a4;return(_a4=this._names)!==null&&_a4!==void 0?_a4:this._names=this._items.reduce((names,c2)=>(c2 instanceof Name&&(names[c2.str]=(names[c2.str]||0)+1),names),{})}};exports._Code=_Code;exports.nil=new _Code("");function _3(strs,...args){let code=[strs[0]],i2=0;for(;i2<args.length;)addCodeArg(code,args[i2]),code.push(strs[++i2]);return new _Code(
|
|
@@ -5355,14 +5359,14 @@ kept only the top-level fields of"}[fit.outcome];if(log2(`${what} tool "${name}"
|
|
|
5355
5359
|
|
|
5356
5360
|
`:"";fitted.push({...tool,description:description+shortenedToolNote(profile.provider),inputSchema:fit.schema})}return fitted}var ROOT_COMBINATORS,REFERENCES,VALUES,SCHEMA_MAPS3,init_mcp_tool_schema=__esm({"server/mcp-tool-schema.ts"(){"use strict";init_tool_schema_profile();ROOT_COMBINATORS=["anyOf","oneOf","allOf","not"];REFERENCES=new Set(["$ref","$dynamicRef","$recursiveRef"]),VALUES=new Set(["const","enum","default","examples","example"]),SCHEMA_MAPS3=new Set(["properties","patternProperties",
|
|
5357
5361
|
"$defs","definitions","dependentSchemas"])}});function drivesItsOwnBrowser(name){return name.startsWith("browser_")||name==="get_browser_state"||name==="page"}function listsComputerTool(name,besideBuiltInBrowser){return!DRIVER_UPKEEP.has(name)&&!BATCH_RUNNERS.has(name)&&!(besideBuiltInBrowser&&drivesItsOwnBrowser(name))}var DRIVER_UPKEEP,BATCH_RUNNERS,init_computer_tool_list=__esm({"server/computer-tool-list.ts"(){"use strict";DRIVER_UPKEEP=new Set(["get_config","set_config","get_recording_state","start_recording","stop_recording","replay_t\
|
|
5358
|
-
rajectory","check_for_update","install_ffmpeg","install_extension","check_permissions","health_report","debug_window_info","get_guide","parse_visual_regions","get_agent_cursor_state","set_agent_cursor_enabled","set_agent_cursor_motion","set_agent_cursor_style","set_agent_cursor_theme","get_session","list_sessions","get_session_state","escalate_session"]),BATCH_RUNNERS=new Set(["run_steps","run_script"])}});import{createHash as createHash24,randomBytes as randomBytes9}from"node:crypto";import{lstat as lstat4,mkdir as mkdir8,readdir as readdir5,unlink as unlink3,writeFile as writeFile5}from"node:fs/promises";import{join as
|
|
5362
|
+
rajectory","check_for_update","install_ffmpeg","install_extension","check_permissions","health_report","debug_window_info","get_guide","parse_visual_regions","get_agent_cursor_state","set_agent_cursor_enabled","set_agent_cursor_motion","set_agent_cursor_style","set_agent_cursor_theme","get_session","list_sessions","get_session_state","escalate_session"]),BATCH_RUNNERS=new Set(["run_steps","run_script"])}});import{createHash as createHash24,randomBytes as randomBytes9}from"node:crypto";import{lstat as lstat4,mkdir as mkdir8,readdir as readdir5,unlink as unlink3,writeFile as writeFile5}from"node:fs/promises";import{join as join80}from"node:path";function chatToolName(server,tool){return`${server}_${tool}`.toLowerCase().replace(/[^a-z0-9_]+/g,"_").replace(/^_+|_+$/g,"").slice(0,64)||"mcp_tool"}function mcpStartupMs(env=process.env){return cloudRole(env)?CLOUD_STARTUP_MS:STARTUP_MS}function object3(value){
|
|
5359
5363
|
return value!==null&&typeof value=="object"&&!Array.isArray(value)}function aborted2(){return new Error("MCP operation cancelled")}function chatMcpEnvironment(serverEnv,source=process.env){let env={...source,PATH:augmentedPath()};return stripControlPlaneEnv(env),{...env,...serverEnv}}function trimmedToolsNotice(trimmed,limit=128){return trimmed.length?`${trimmed.map(({server,listed:listed2,of})=>`"${server}" listed ${listed2} of ${of} tools`).join(", ")} to fit the model's ${limit}-tool limit; t\
|
|
5360
5364
|
he rest are left out of this turn.`:void 0}function quotedList(names){let quoted2=names.map(name=>`"${name}"`);return quoted2.length===1?quoted2[0]:`${quoted2.slice(0,-1).join(", ")} and ${quoted2.at(-1)}`}function mergedServersNotice({server,same}){return`MCP ${same.length===1?"server":"servers"} ${quotedList(same)} ${same.length===1?"connects":"connect"} to the same address with the same sign-in as "${server}", so their tools are listed once, under "${server}".`}function searchedServersNotice(budget){
|
|
5361
5365
|
let names=budget.servers.filter(server=>!server.direct).map(server=>server.name);if(names.length)return`To fit the model's ${budget.limit}-tool limit, the tools of ${quotedList(names)} are reached through the tool search this turn.`}function toolLimitNotices(session){return[trimmedToolsNotice(session.trimmed,session.budget.limit),searchedServersNotice(session.budget)].filter(line3=>line3!==void 0)}async function refitChatTools(session,error62,key2,runtime){let limit=toolCountLimitFromError(error62);
|
|
5362
5366
|
if(limit===void 0||limit>=session.definitions.length)return;learnToolCountLimit(key2,limit),console.warn(`chat-mcp: the model takes at most ${limit} tools; listing the turn's tools again within that`);let kept=session.definitions.filter(definition2=>runtime.includes(definition2));return await session.refit(limit),session.definitions.push(...kept),toolLimitNotices(session)}function chatToolNotices(session){return[...(session.merged??[]).map(mergedServersNotice),...session.skipped.map(({server,reason})=>`\
|
|
5363
5367
|
MCP server "${server}" was skipped for this turn: ${reason}`),...toolLimitNotices(session)]}function preview(bytes2){let end=OUTPUT_BYTES;for(;(bytes2[end]&192)===128;)end-=1;return bytes2.subarray(0,end).toString()}function boundedText(value,bytes2=Buffer.from(value)){return bytes2.length<=OUTPUT_BYTES?value:`${preview(bytes2)}
|
|
5364
|
-
[MCP result truncated at 50KB; request less output.]`}async function pruneSavedResults(dir,keep){let saved=(await readdir5(dir)).flatMap(name=>{let match=name===keep?null:SAVED_RESULT_NAME.exec(name);return match?[{name,at:Number(match[1])}]:[]}).sort((a2,b3)=>b3.at-a2.at);await Promise.all(saved.slice(SAVED_RESULTS_KEPT-1).map(({name})=>unlink3(
|
|
5365
|
-
value,bytes2);try{let dir=
|
|
5368
|
+
[MCP result truncated at 50KB; request less output.]`}async function pruneSavedResults(dir,keep){let saved=(await readdir5(dir)).flatMap(name=>{let match=name===keep?null:SAVED_RESULT_NAME.exec(name);return match?[{name,at:Number(match[1])}]:[]}).sort((a2,b3)=>b3.at-a2.at);await Promise.all(saved.slice(SAVED_RESULTS_KEPT-1).map(({name})=>unlink3(join80(dir,name))))}async function savedOrBounded(value,tool,folder,scrub2){let bytes2=Buffer.from(value);if(bytes2.length<=OUTPUT_BYTES||!folder)return boundedText(
|
|
5369
|
+
value,bytes2);try{let dir=join80(folder,SAVED_RESULTS_FOLDER);if(await mkdir8(dir,{recursive:!0,mode:448}),!(await lstat4(dir)).isDirectory())throw new Error("not a folder");let name=`result-${tool}-${Date.now()}-${randomBytes9(3).toString("hex")}.txt`,file2=join80(dir,name),kept=scrub2(value);if(Buffer.byteLength(kept)>MESSAGE_FILE_MAX_BYTES)return boundedText(value,bytes2);await writeFile5(file2,kept,{flag:"wx",mode:384}),await pruneSavedResults(dir,name).catch(()=>{});let kb=Math.ceil(bytes2.
|
|
5366
5370
|
length/1024),masked=kept===value?"":" (secret-looking values in it are masked)";return`${preview(bytes2)}
|
|
5367
5371
|
[MCP result is ${kb}KB; only the first 50KB is shown above. The full result is saved in ${file2}${masked}]`}catch{return boundedText(value,bytes2)}}function normalizeBuiltInBrowserArgs(tool,args){if(object3(args)){for(let field of BUILT_IN_BROWSER_BLANK_MEANS_OMITTED[tool]??[]){let value=args[field];typeof value=="string"&&!value.trim()&&delete args[field]}tool==="agent_browser_screenshot"&&(args.ref!==void 0&&args.selector!==void 0&&delete args.selector,(args.ref!==void 0||args.selector!==void 0)&&
|
|
5368
5372
|
(delete args.x,delete args.y))}}function loopbackNavigationHint(tool,args,text13,env=process.env){return env.OMB_DESKTOP_PARENT==="1"||cloudHomeConfigured(env)||!/^agent_browser_(?:open|navigate)$/u.test(tool)||!object3(args)||typeof args.url!="string"||!ROUTE_LOOPBACK.test(args.url.trim())||!/(?:ERR_[A-Z_]+|failed)/u.test(text13)?"":" That address is the loopback of the machine running this browser, not your own computer: open the site by the LAN address it answers on (for example http://192.16\
|
|
@@ -5481,12 +5485,12 @@ result:shorten(envelope.result)}):shorten(content3)}}function smallerResend(mess
|
|
|
5481
5485
|
index2=>index2<requestAt).map(index2=>()=>replace(index2,null))],taken=0;for(;taken<steps.length&&total>target2;taken++)steps[taken]();if(!taken)return null;let dropped=out.slice(0,requestAt).filter(message5=>message5===null).length,firstDropped=out.indexOf(null),kept=out.flatMap((message5,index2)=>[...dropped&&index2===firstDropped?[{role:"assistant",content:omittedHistory(dropped)}]:[],...message5?[message5]:[]]);return{messages:kept,before:{...before,bytes:refusedBytes},after:requestSize(kept,
|
|
5482
5486
|
overhead)}}function sizeChange(before,after){return`${before.bytes} \u2192 ${after.bytes} bytes, ${before.messages} \u2192 ${after.messages} messages, ${before.images} \u2192 ${after.images} images`}var TOO_LARGE,RequestTooLargeError,IMAGE_OMITTED,TOOL_OUTPUT_SHORTENED,omittedHistory,LONG_TOOL_OUTPUT_BYTES,SHORT_TOOL_OUTPUT_BYTES,bytesOf,isImage,imagesIn,init_chat_size_limit=__esm({"server/drivers/chat-size-limit.ts"(){"use strict";init_context_rebuild();init_openai_chat_protocol();TOO_LARGE=/\b(?:request entity|payload|request) too large\b/i;
|
|
5483
5487
|
RequestTooLargeError=class extends Error{bytes;constructor(message5,bytes2){super(message5),this.bytes=bytes2}},IMAGE_OMITTED="[image omitted to fit the provider's size limit]",TOOL_OUTPUT_SHORTENED=`
|
|
5484
|
-
[tool output shortened to fit the provider's size limit]`,omittedHistory=count5=>`[${count5} earlier message${count5===1?"":"s"} omitted to fit the provider's size limit; full history remains in the app.]`,LONG_TOOL_OUTPUT_BYTES=4e3,SHORT_TOOL_OUTPUT_BYTES=1e3,bytesOf=value=>Buffer.byteLength(JSON.stringify(value)),isImage=part=>part.type==="image_url",imagesIn=message5=>Array.isArray(message5.content)?message5.content.filter(isImage).length:0}});function requestTooLargeMessage(model){return`This message is too large for ${model}. Start a new chat or pick a model that accepts more.`}var init_request_too_large=__esm({"shared/request-too-large.ts"(){"use strict"}});import{mkdirSync as
|
|
5488
|
+
[tool output shortened to fit the provider's size limit]`,omittedHistory=count5=>`[${count5} earlier message${count5===1?"":"s"} omitted to fit the provider's size limit; full history remains in the app.]`,LONG_TOOL_OUTPUT_BYTES=4e3,SHORT_TOOL_OUTPUT_BYTES=1e3,bytesOf=value=>Buffer.byteLength(JSON.stringify(value)),isImage=part=>part.type==="image_url",imagesIn=message5=>Array.isArray(message5.content)?message5.content.filter(isImage).length:0}});function requestTooLargeMessage(model){return`This message is too large for ${model}. Start a new chat or pick a model that accepts more.`}var init_request_too_large=__esm({"shared/request-too-large.ts"(){"use strict"}});import{mkdirSync as mkdirSync32,writeFileSync as writeFileSync17}from"node:fs";import{homedir as homedir23}from"node:os";import{join as join81,resolve as resolve25}from"node:path";function handoffDir(){return resolve25(process.env.OMB_DATA_DIR||join81(homedir23(),".limixbot"),"handoffs")}function writeTurnHandoff(input2){try{let dir=handoffDir();mkdirSync32(dir,{recursive:!0});let stamp2=new Date().toISOString().replace(/[:.]/g,"-"),file2=join81(dir,`cap-${String(input2.threadId).slice(0,8)}-${String(
|
|
5485
5489
|
input2.turnId).slice(0,8)}-${stamp2}.md`),L2=[];L2.push("# Handoff - turn ended without a final answer",""),L2.push(`- Thread: ${input2.threadId}`),L2.push(`- Turn: ${input2.turnId}`),L2.push(`- Model: ${input2.model??"unknown"}`),L2.push(`- Tool calls used: ${input2.toolCalls}`),input2.hasUsage&&input2.usage&&L2.push(`- Tokens this turn: ${input2.usage.input} in / ${input2.usage.output} out`),L2.push(`- Stop reason: ${input2.failure??"unknown"}`),L2.push(`- Written at: ${new Date().toISOString()}`,
|
|
5486
5490
|
""),L2.push("## Original task (first user message)","```");let firstUser=input2.messages.find(m3=>m3.role==="user"),firstText2=firstUser&&typeof firstUser.content=="string"?firstUser.content:JSON.stringify(firstUser?.content??null);L2.push(String(firstText2).slice(0,8e3),"```",""),L2.push("## Work performed (tool calls in order)","");let n3=0;for(let m3 of input2.messages)if(m3.role==="assistant"&&Array.isArray(m3.tool_calls))for(let tc of m3.tool_calls){n3+=1;let args=String(tc.function?.arguments??
|
|
5487
5491
|
"").replace(/\s+/g," ").slice(0,300);L2.push(`${n3}. ${tc.function?.name??"tool"} - ${args}`)}else if(m3.role==="tool"){let verdict="?";try{verdict=JSON.parse(String(m3.content)).ok?"ok":"FAILED"}catch{}L2.push(` result ${verdict}: ${String(m3.content??"").replace(/\s+/g," ").slice(0,220)}`)}n3===0&&L2.push("(none recorded)"),L2.push("","## Last assistant text","");let last=null;for(let i2=input2.messages.length-1;i2>=0;i2-=1){let c2=input2.messages[i2].content;if(input2.messages[i2].role==="a\
|
|
5488
5492
|
ssistant"&&typeof c2=="string"&&c2.trim()){last=c2;break}}return L2.push(last?last.slice(0,6e3):"(none)",""),L2.push("## Instructions for whoever continues this task",""),L2.push("1. Read this file completely."),L2.push("2. Re-verify the current state of every file, branch, and PR mentioned above before acting - it may be stale."),L2.push("3. Continue from the first unfinished step. Do not redo completed work."),L2.push("4. If you get close to your own turn budget, append your progress to this f\
|
|
5489
|
-
ile before stopping."),
|
|
5493
|
+
ile before stopping."),writeFileSync17(file2,L2.join(`
|
|
5490
5494
|
`),{mode:384}),file2}catch{return null}}function classifyContinuable(_stopReason,failure2){return failure2&&CAP_STOP.test(failure2)?"cap":null}var CAP_STOP,init_turn_continuation=__esm({"server/turn-continuation.ts"(){"use strict";CAP_STOP=/^(?:stopped after \d+ [a-z ]+ without a final answer|model-call limit reached)/i}});var require_symbols=__commonJS({"node_modules/.pnpm/undici@8.11.2/node_modules/undici/lib/core/symbols.js"(exports,module){"use strict";module.exports={kClose:Symbol("close"),kDestroy:Symbol("destroy"),kDispatch:Symbol("dispatch"),kUrl:Symbol("url"),kRequestOrigin:Symbol("request origin"),kOriginless:Symbol("originless"),kWriting:Symbol("writing"),kResuming:Symbol("resuming"),kQueue:Symbol("queue"),kConnect:Symbol("connect"),kConnecting:Symbol("connecting"),kKeepAliveDefaultTimeout:Symbol("defau\
|
|
5491
5495
|
lt keep alive timeout"),kKeepAliveMaxTimeout:Symbol("max keep alive timeout"),kKeepAliveTimeoutThreshold:Symbol("keep alive timeout threshold"),kKeepAliveTimeoutValue:Symbol("keep alive timeout"),kKeepAlive:Symbol("keep alive"),kHeadersTimeout:Symbol("headers timeout"),kBodyTimeout:Symbol("body timeout"),kServerName:Symbol("server name"),kLocalAddress:Symbol("local address"),kHost:Symbol("host"),kNoRef:Symbol("no ref"),kBodyUsed:Symbol("used"),kBody:Symbol("abstracted request body"),kRunning:Symbol(
|
|
5492
5496
|
"running"),kBlocking:Symbol("blocking"),kPending:Symbol("pending"),kSize:Symbol("size"),kBusy:Symbol("busy"),kQueued:Symbol("queued"),kFree:Symbol("free"),kConnected:Symbol("connected"),kClosed:Symbol("closed"),kNeedDrain:Symbol("need drain"),kReset:Symbol("reset"),kDestroyed:Symbol.for("nodejs.stream.destroyed"),kResume:Symbol("resume"),kOnError:Symbol("on error"),kMaxHeadersSize:Symbol("max headers size"),kRunningIdx:Symbol("running index"),kPendingIdx:Symbol("pending index"),kError:Symbol("er\
|
|
@@ -6761,7 +6765,7 @@ let i2=0,j2=potentialValue.length;for(;j2>i2&&isHTTPWhiteSpaceCharCode(potential
|
|
|
6761
6765
|
isValidHeaderName(name)){if(!isValidHeaderValue(value))throw webidl.errors.invalidArgument({prefix:"Headers.append",value,type:"header value"})}else throw webidl.errors.invalidArgument({prefix:"Headers.append",value:name,type:"header name"});if(getHeadersGuard(headers)==="immutable")throw new TypeError("immutable");return getHeadersList(headers).append(name,value,!1)}function headersListSortAndCombine(target2){let headersList=getHeadersList(target2);if(!headersList)return[];if(headersList.sortedMap)
|
|
6762
6766
|
return headersList.sortedMap;let headers=[],names=headersList.toSortedArray(),cookies=headersList.cookies;if(cookies===null||cookies.length===1)return headersList.sortedMap=names;for(let i2=0;i2<names.length;++i2){let{0:name,1:value}=names[i2];if(name==="set-cookie")for(let j2=0;j2<cookies.length;++j2)headers.push([name,cookies[j2]]);else headers.push([name,value])}return headersList.sortedMap=headers}function compareHeaderName(a2,b3){return a2[0]<b3[0]?-1:1}var HeadersList=class _HeadersList{cookies=null;sortedMap;headersMap;constructor(init){
|
|
6763
6767
|
init instanceof _HeadersList?(this.headersMap=new Map(init.headersMap),this.sortedMap=init.sortedMap,this.cookies=init.cookies===null?null:[...init.cookies]):(this.headersMap=new Map(init),this.sortedMap=null)}contains(name,isLowerCase){return this.headersMap.has(isLowerCase?name:name.toLowerCase())}clear(){this.headersMap.clear(),this.sortedMap=null,this.cookies=null}append(name,value,isLowerCase){this.sortedMap=null;let lowercaseName=isLowerCase?name:name.toLowerCase(),exists=this.headersMap.get(
|
|
6764
|
-
lowercaseName);if(exists){let
|
|
6768
|
+
lowercaseName);if(exists){let delimiter11=lowercaseName==="cookie"?"; ":", ";this.headersMap.set(lowercaseName,{name:exists.name,value:`${exists.value}${delimiter11}${value}`})}else this.headersMap.set(lowercaseName,{name,value});lowercaseName==="set-cookie"&&(this.cookies??=[]).push(value)}set(name,value,isLowerCase){this.sortedMap=null;let lowercaseName=isLowerCase?name:name.toLowerCase();lowercaseName==="set-cookie"&&(this.cookies=[value]),this.headersMap.set(lowercaseName,{name,value})}delete(name,isLowerCase){
|
|
6765
6769
|
this.sortedMap=null,isLowerCase||(name=name.toLowerCase()),name==="set-cookie"&&(this.cookies=null),this.headersMap.delete(name)}get(name,isLowerCase){return this.headersMap.get(isLowerCase?name:name.toLowerCase())?.value??null}*[Symbol.iterator](){for(let{0:name,1:{value}}of this.headersMap)yield[name,value]}get entries(){let headers={};if(this.headersMap.size!==0)for(let{name,value}of this.headersMap.values())headers[name]=value;return headers}rawValues(){return this.headersMap.values()}get entriesList(){
|
|
6766
6770
|
let headers=[];if(this.headersMap.size!==0)for(let{0:lowerName,1:{name,value}}of this.headersMap)if(lowerName==="set-cookie")for(let cookie of this.cookies)headers.push([name,cookie]);else headers.push([name,value]);return headers}toSortedArray(){let size=this.headersMap.size,array2=new Array(size);if(size<=32){if(size===0)return array2;let iterator=this.headersMap[Symbol.iterator](),firstValue=iterator.next().value;array2[0]=[firstValue[0],firstValue[1].value],assert2(firstValue[1].value!==null);
|
|
6767
6771
|
for(let i2=1,j2=0,right=0,left=0,pivot=0,x2,value;i2<size;++i2){for(value=iterator.next().value,x2=array2[i2]=[value[0],value[1].value],assert2(x2[1]!==null),left=0,right=i2;left<right;)pivot=left+(right-left>>1),array2[pivot][0]<=x2[0]?left=pivot+1:right=pivot;if(i2!==pivot){for(j2=i2;j2>left;)array2[j2]=array2[--j2];array2[left]=x2}}if(!iterator.next().done)throw new TypeError("Unreachable");return array2}else{let i2=0;for(let{0:name,1:{value}}of this.headersMap)array2[i2++]=[name,value],assert2(
|
|
@@ -7504,13 +7508,13 @@ indent:this.indent,items:[{start,key:null,sep:[this.sourceToken]}]}}}return null
|
|
|
7504
7508
|
d":case"map-value-ind":yield*this.pop(),yield*this.step();break;case"newline":this.onKeyLine=!1;default:token.end?token.end.push(this.sourceToken):token.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop())}}}}});function parseOptions(options2){let prettyErrors=options2.prettyErrors!==!1;return{lineCounter:options2.lineCounter||prettyErrors&&new LineCounter||null,prettyErrors}}function parseDocument(source,options2={}){let{lineCounter,prettyErrors}=parseOptions(options2),parser=new Parser(lineCounter?.addNewLine),composer=new Composer(options2),doc=null;for(let _doc of composer.compose(parser.parse(source),!0,source.length))if(!doc)doc=_doc;else if(doc.options.logLevel!=="silent"){doc.errors.push(new YAMLParseError(
|
|
7505
7509
|
_doc.range.slice(0,2),"MULTIPLE_DOCS","Source contains multiple documents; please use YAML.parseAllDocuments()"));break}return prettyErrors&&lineCounter&&(doc.errors.forEach(prettifyError2(source,lineCounter)),doc.warnings.forEach(prettifyError2(source,lineCounter))),doc}function parse4(src,reviver,options2){let _reviver;typeof reviver=="function"?_reviver=reviver:options2===void 0&&reviver&&typeof reviver=="object"&&(options2=reviver);let doc=parseDocument(src,options2);if(!doc)return null;if(doc.
|
|
7506
7510
|
warnings.forEach(warning=>warn2(doc.options.logLevel,warning)),doc.errors.length>0){if(doc.options.logLevel!=="silent")throw doc.errors[0];doc.errors=[]}return doc.toJS(Object.assign({reviver:_reviver},options2))}function stringify3(value,replacer,options2){let _replacer=null;if(typeof replacer=="function"||Array.isArray(replacer)?_replacer=replacer:options2===void 0&&replacer&&(options2=replacer),typeof options2=="string"&&(options2=options2.length),typeof options2=="number"){let indent=Math.round(
|
|
7507
|
-
options2);options2=indent<1?void 0:indent>8?{indent:8}:{indent}}if(value===void 0){let{keepUndefined}=options2??replacer??{};if(!keepUndefined)return}return isDocument(value)&&!_replacer?value.toString(options2):new Document(value,_replacer,options2).toString(options2)}var init_public_api=__esm({"node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/public-api.js"(){init_composer();init_Document();init_errors5();init_log();init_identity3();init_line_counter();init_parser()}});var init_dist5=__esm({"node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/index.js"(){init_composer();init_Document();init_Schema();init_errors5();init_Alias();init_identity3();init_Pair();init_Scalar();init_YAMLMap();init_YAMLSeq();init_cst();init_lexer();init_line_counter();init_parser();init_public_api();init_visit2()}});var init_browser2=__esm({"node_modules/yaml/browser/index.js"(){init_dist5();init_dist5()}});import{existsSync as
|
|
7511
|
+
options2);options2=indent<1?void 0:indent>8?{indent:8}:{indent}}if(value===void 0){let{keepUndefined}=options2??replacer??{};if(!keepUndefined)return}return isDocument(value)&&!_replacer?value.toString(options2):new Document(value,_replacer,options2).toString(options2)}var init_public_api=__esm({"node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/public-api.js"(){init_composer();init_Document();init_errors5();init_log();init_identity3();init_line_counter();init_parser()}});var init_dist5=__esm({"node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/index.js"(){init_composer();init_Document();init_Schema();init_errors5();init_Alias();init_identity3();init_Pair();init_Scalar();init_YAMLMap();init_YAMLSeq();init_cst();init_lexer();init_line_counter();init_parser();init_public_api();init_visit2()}});var init_browser2=__esm({"node_modules/yaml/browser/index.js"(){init_dist5();init_dist5()}});import{existsSync as existsSync31,readFileSync as readFileSync43,statSync as statSync21,writeFileSync as writeFileSync18}from"node:fs";import{dirname as dirname32,join as join82,resolve as resolve26}from"node:path";import{setTimeout as delay2}from"node:timers/promises";function grokHome(env=process.env){return env.GROK_HOME||harnessHome("grok",env)}function grokSignedIn(env){return existsSync31(join82(grokHome(env),"auth.json"))}function grokSignInState(env){try{return statSync21(join82(grokHome(
|
|
7508
7512
|
env),"auth.json")),"signed-in"}catch(error62){return error62.code==="ENOENT"?"signed-out":"unknown"}}function grokLoginFailure(output2){return/(unexpected argument|unrecognized (argument|option)|unknown option).*device-(auth|code)/i.test(output2)?"This server's Grok is too old to sign in with a code. Update Grok on the server, then try again.":/device-code login is not available/i.test(output2)?"This Grok account can't sign in with a code. Use an xAI API key instead.":/expired/i.test(output2)?"T\
|
|
7509
7513
|
he Grok sign-in code expired. Start sign-in again for a new code.":/denied|rejected/i.test(output2)?"Grok sign-in was declined in the browser. Start sign-in again to try once more.":"Grok sign-in did not finish. Check the server's connection, then try again."}function unquote2(raw){let value=raw.trim();return value.length>=2&&value.startsWith('"')&&value.endsWith('"')?value.slice(1,-1).replace(/\\"/g,'"'):value}function readGrokModelCatalog(env=process.env){let fixed=currentEngineCatalog("grok"),
|
|
7510
|
-
path3=
|
|
7514
|
+
path3=join82(grokHome(env),"config.toml"),text13="";try{text13=readFileSync43(path3,"utf8")}catch{return fixed}let options2=fixed.options.map(o=>({...o})),seen=new Set(options2.map(o=>o.id)),configuredDefault=null,current=null,inModels=!1,flush=()=>{if(!current||!SLUG.test(current.slug)||seen.has(current.slug)){current=null;return}seen.add(current.slug),options2.push({id:current.slug,label:current.name||current.slug,custom:!0}),current=null};for(let line3 of text13.split(/\r?\n/)){let stripped=line3.
|
|
7511
7515
|
trim();if(stripped==="[models]"){flush(),inModels=!0;continue}if(stripped.startsWith("[model.")&&stripped.endsWith("]")){flush(),inModels=!1;let inner=stripped.slice(7,-1);inner.startsWith('"')&&inner.endsWith('"')&&(inner=inner.slice(1,-1)),current={slug:inner};continue}if(stripped.startsWith("[")){flush(),inModels=!1;continue}if(!stripped||stripped.startsWith("#")||!stripped.includes("="))continue;let eq=stripped.indexOf("="),key2=stripped.slice(0,eq).trim(),value=unquote2(stripped.slice(eq+1));
|
|
7512
7516
|
current&&key2==="name"&&value&&(current.name=value),!current&&inModels&&key2==="default"&&(configuredDefault=value)}return flush(),{default:configuredDefault&&seen.has(configuredDefault)?configuredDefault:fixed.default,options:options2}}function suggestGrokSlug(host2,model,taken){let base2=`${host2}-${model}`.toLowerCase().replace(/[^a-z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");(!base2||!/^[a-z]/.test(base2))&&(base2=`m-${base2||"model"}`);let slug2=base2,n3=2;for(;taken.has(slug2);)
|
|
7513
|
-
slug2=`${base2}-${n3}`,n3+=1;return slug2}function quoteToml(value){return`"${value.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function ensureGrokInjectSlug(modelId2,env=process.env){let inject=decodeInjectId(modelId2);if(!inject)return modelId2;let host2=localHost(inject.host);if(!host2)return modelId2;let path3=
|
|
7517
|
+
slug2=`${base2}-${n3}`,n3+=1;return slug2}function quoteToml(value){return`"${value.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function ensureGrokInjectSlug(modelId2,env=process.env){let inject=decodeInjectId(modelId2);if(!inject)return modelId2;let host2=localHost(inject.host);if(!host2)return modelId2;let path3=join82(grokHome(env),"config.toml"),text13="";try{text13=readFileSync43(path3,"utf8")}catch{text13=""}let taken=new Set(currentEngineCatalog("grok").options.map(option=>option.id)),current=null,
|
|
7514
7518
|
flush=()=>{current&&(taken.add(current.slug),current.model===inject.model&¤t.baseUrl===host2.baseUrl&&(found=current.slug),current=null)},found=null;for(let line3 of text13.split(/\r?\n/)){let stripped=line3.trim();if(stripped.startsWith("[model.")&&stripped.endsWith("]")){flush();let inner=stripped.slice(7,-1);inner.startsWith('"')&&inner.endsWith('"')&&(inner=inner.slice(1,-1)),current={slug:inner};continue}if(stripped.startsWith("[")){flush();continue}if(!current||!stripped.includes("="))
|
|
7515
7519
|
continue;let eq=stripped.indexOf("="),key2=stripped.slice(0,eq).trim(),value=unquote2(stripped.slice(eq+1));key2==="model"&&(current.model=value),key2==="base_url"&&(current.baseUrl=value)}if(flush(),found)return found;let slug2=suggestGrokSlug(inject.host,inject.model,taken),block2=[/[^a-z0-9_-]/i.test(slug2)?`[model."${slug2}"]`:`[model.${slug2}]`,`model = ${quoteToml(inject.model)}`,`base_url = ${quoteToml(host2.baseUrl)}`,`name = ${quoteToml(`${inject.model} (${host2.label})`)}`,'api_backend\
|
|
7516
7520
|
= "chat_completions"',`api_key = ${quoteToml(hostApiKey(host2,env))}`,""].join(`
|
|
@@ -7518,11 +7522,11 @@ continue;let eq=stripped.indexOf("="),key2=stripped.slice(0,eq).trim(),value=unq
|
|
|
7518
7522
|
`)?`${text13}
|
|
7519
7523
|
|
|
7520
7524
|
${block2}`:`${text13}${text13?`
|
|
7521
|
-
`:""}${block2}`;return
|
|
7525
|
+
`:""}${block2}`;return writeFileSync18(path3,next),slug2}function grokAcceptsUnadvertisedImages(init){let meta3=init?._meta;if(meta3?.grokShell!==!0||typeof meta3.agentVersion!="string")return!1;let version2=/^1\.0\.(\d+)$/.exec(meta3.agentVersion);return!!(version2&&Number(version2[1])>=25)}function grokInheritedProfile(cli,env,cwd){let unsupported=()=>{throw new Error("Grok's existing agent profile cannot be safely intersected with tool selection. Use a profile file with explicit tools or a se\
|
|
7522
7526
|
parate default Grok account.")};if(env.GROK_AGENT&&env.GROK_AGENT!=="grok-build"||env.GROK_CONFIG||env.GROK_CONFIG_PATH)return unsupported();let args=splitCliString(cli);if(args.some(arg=>/^(--tools|--disallowed-tools|--disallowedTools|--agent)(=|$)/.test(arg)))return unsupported();let flags=args.flatMap((arg,index2)=>arg==="--agent-profile"||arg.startsWith("--agent-profile=")?[index2]:[]);if(flags.length>1)return unsupported();let flag3=flags[0]??-1,path3=flag3>=0?args[flag3].includes("=")?args[flag3].
|
|
7523
|
-
slice(args[flag3].indexOf("=")+1):args[flag3+1]:void 0;if(flag3>=0&&(!path3||path3.startsWith("-")))return unsupported();let files=[
|
|
7527
|
+
slice(args[flag3].indexOf("=")+1):args[flag3+1]:void 0;if(flag3>=0&&(!path3||path3.startsWith("-")))return unsupported();let files=[join82(grokHome(env),"config.toml")];for(let directory=resolve26(cwd);;){let file2=join82(directory,".grok","config.toml");files.includes(file2)||files.push(file2);let parent=dirname32(directory);if(parent===directory)break;directory=parent}for(let file2 of files){if(!existsSync31(file2))continue;let text14=readFileSync43(file2,"utf8");if(text14.length>262144)return unsupported();
|
|
7524
7528
|
let section="";for(let line3 of text14.split(/\r?\n/).map(line4=>line4.trim()).filter(line4=>line4&&!line4.startsWith("#"))){let header=/^\[([A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)*)\]\s*(?:#.*)?$/.exec(line3);if(header){if(section=header[1],section.startsWith("agent."))return unsupported();continue}let assignment=/^([A-Za-z0-9_-]+)\s*=\s*(.+)$/.exec(line3);if(!assignment||/'''|"""/.test(assignment[2])||!section&&assignment[1]==="agent")return unsupported();if(section!=="agent")continue;let match2=/^(name|definition)\s*=\s*("(?:[^"\\]|\\.)*"|'[^']*')\s*(?:#.*)?$/.
|
|
7525
|
-
exec(line3);if(!match2)return unsupported();let value;try{value=match2[2].startsWith('"')?JSON.parse(match2[2]):match2[2].slice(1,-1)}catch{return unsupported()}if(value.includes("$")||!value||match2[1]==="name"&&value!=="grok-build")return unsupported();if(match2[1]==="definition"&&flag3<0){if(path3!==void 0&&path3!==value)return unsupported();path3=value}}}if(!path3)return;let text13=
|
|
7529
|
+
exec(line3);if(!match2)return unsupported();let value;try{value=match2[2].startsWith('"')?JSON.parse(match2[2]):match2[2].slice(1,-1)}catch{return unsupported()}if(value.includes("$")||!value||match2[1]==="name"&&value!=="grok-build")return unsupported();if(match2[1]==="definition"&&flag3<0){if(path3!==void 0&&path3!==value)return unsupported();path3=value}}}if(!path3)return;let text13=readFileSync43(resolve26(cwd,path3),"utf8");if(text13.length>262144)return unsupported();let match=/^\s*---\r?\n([\s\S]*?)\r?\n---(?:\r?\n([\s\S]*))?$/.
|
|
7526
7530
|
exec(text13);if(!match)return unsupported();let profile=parse4(match[1]);if(!profile||typeof profile.name!="string"||typeof profile.description!="string"||profile.tools!==void 0&&(!Array.isArray(profile.tools)||!profile.tools.every(tool=>typeof tool=="string"))||profile.disallowedTools!==void 0&&(!Array.isArray(profile.disallowedTools)||!profile.disallowedTools.every(tool=>typeof tool=="string")))return unsupported();let toolConfig=profile.toolConfig??{tools:GROK_NATIVE_TOOLS.map(([name,id])=>({
|
|
7527
7531
|
id,name_override:name}))};return!Array.isArray(toolConfig.tools)||!toolConfig.tools.every(tool=>typeof tool?.id=="string"&&(tool.name_override===void 0||typeof tool.name_override=="string"))?unsupported():{...profile,name:profile.name,description:profile.description,toolConfig,...match[2]?.trim()?{promptBody:match[2].trim()}:{}}}function grokToolScopeProfile(scope,init,inherited,hasMcp=!1){let parsed=parseToolScope(scope);if(!parsed.ok)throw new Error(parsed.error);let meta3=init?._meta;if(meta3?.
|
|
7528
7532
|
grokShell!==!0||meta3.agentVersion!=="1.0.41")throw new Error("This Grok runtime does not have verified native tool selection. Use Grok 1.0.41 or Pi; update Grok support before using another version.");if(hasMcp&&(!allowsTool(scope,{kind:"native",name:"search_tool"})||!allowsTool(scope,{kind:"native",name:"use_tool"})))throw new Error("Grok requires native:search_tool and native:use_tool to find and call selected MCP tools. Allow both explicitly or use Pi.");let selected=(inherited?.toolConfig.tools??
|
|
@@ -7544,15 +7548,15 @@ if(catalog.sessionMcpResolved===!0){if([...available].some(name=>!catalog.server
|
|
|
7544
7548
|
toolScope})=>{if(toolScope!==void 0&&(env.GROK_MANAGED_MCPS_ENABLED="false",env.GROK_MANAGED_MCP_GATEWAY_TOOLS_ENABLED="false",narrowsNativeTools(toolScope))){if(env.GROK_AGENT&&env.GROK_AGENT!=="grok-build")throw new Error("Grok's existing agent profile cannot be safely intersected with tool selection. Use a separate default Grok account.");env.GROK_AGENT="grok-build"}},pickAuthMethod:methods=>["cached_token","grok.com"].find(id=>methods.some(m3=>m3.id===id))??null,authFailure:"fail",isAuthenticated:env=>grokSignedIn(
|
|
7545
7549
|
env),buildPromptText:turn=>turn.system?`${turn.system}
|
|
7546
7550
|
|
|
7547
|
-
${turn.text}`:turn.text},GrokAgentDriver=createAcpDriver(support2)}});import{existsSync as
|
|
7548
|
-
isFinite(creds.expiry_date)?!1:Date.now()<creds.expiry_date||hasRefresh:!0}catch{return!1}}function geminiIsAuthenticated(env){return nonBlank(env.GEMINI_API_KEY)||nonBlank(env.GOOGLE_API_KEY)||
|
|
7551
|
+
${turn.text}`:turn.text},GrokAgentDriver=createAcpDriver(support2)}});import{existsSync as existsSync32,readFileSync as readFileSync44}from"node:fs";import{join as join83}from"node:path";function liveOauthCredential(env){try{let creds=JSON.parse(readFileSync44(join83(userHome(env),".gemini","oauth_creds.json"),"utf8"));if(typeof creds.access_token!="string"||creds.access_token.trim().length===0)return!1;let hasRefresh=typeof creds.refresh_token=="string"&&creds.refresh_token.trim().length>0;return creds.expiry_date!==void 0?typeof creds.expiry_date!="number"||!Number.
|
|
7552
|
+
isFinite(creds.expiry_date)?!1:Date.now()<creds.expiry_date||hasRefresh:!0}catch{return!1}}function geminiIsAuthenticated(env){return nonBlank(env.GEMINI_API_KEY)||nonBlank(env.GOOGLE_API_KEY)||existsSync32(join83(userHome(env),".gemini","oauth_creds.json"))&&liveOauthCredential(env)}function geminiApprovalArgs(fullAuto,approvalMode){return fullAuto?["--yolo"]:approvalMode==="edits"?["--approval-mode","auto_edit"]:[]}var AUTH_PREFERENCE,nonBlank,support3,GeminiAgentDriver,init_gemini=__esm({"ser\
|
|
7549
7553
|
ver/drivers/acp/gemini.ts"(){"use strict";init_env_path();init_core3();AUTH_PREFERENCE=["gemini-api-key","oauth-personal","vertex-ai"];nonBlank=value=>!!value?.trim();support3={driverKind:"geminiAgent",displayName:"Gemini",models:{default:"gemini-2.5-pro",options:[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"}]},defaultCli:"gemini",nativeSource:"gemini.acp",loginNote:"Gemini CLI needs a GEMINI_API_KEY, a Vertex AI setup, or an enterprise Code Assist\
|
|
7550
7554
|
login \u2014 consumer Google logins stopped working on 2026-06-18 (use the Antigravity engine for those accounts)",install:{command:{darwin:"npm install -g @google/gemini-cli",linux:"npm install -g @google/gemini-cli",win32:"npm install -g @google/gemini-cli"},npmPackage:"@google/gemini-cli",docsUrl:"https://github.com/google-gemini/gemini-cli"},spawnArgs:(config3,turn)=>["--acp",...geminiApprovalArgs(config3.fullAuto,turn.approvalMode),...turn.model?["-m",turn.model]:[]],credentialEnv:["GEMINI\
|
|
7551
7555
|
_API_KEY","GOOGLE_API_KEY"],pickAuthMethod:methods=>{let ids=methods.map(m3=>m3.id).filter(id=>typeof id=="string");for(let pref of AUTH_PREFERENCE)if(ids.includes(pref))return pref;return ids[0]??null},authFailure:"continue",isAuthenticated:geminiIsAuthenticated,buildPromptText:turn=>turn.system?`${turn.system}
|
|
7552
7556
|
|
|
7553
|
-
${turn.text}`:turn.text},GeminiAgentDriver=createAcpDriver(support3)}});import{mkdirSync as
|
|
7554
|
-
parse(
|
|
7555
|
-
readdirSync18(credentials)}catch(error62){return error62.code==="ENOENT"?"signed-out":"unknown"}return names.some(name=>KIMI_TOKEN_FILE.test(name)&&kimiTokenHeld(
|
|
7557
|
+
${turn.text}`:turn.text},GeminiAgentDriver=createAcpDriver(support3)}});import{mkdirSync as mkdirSync33,readdirSync as readdirSync18,readFileSync as readFileSync45,unlinkSync as unlinkSync10,writeFileSync as writeFileSync19}from"node:fs";import{homedir as homedir24}from"node:os";import{join as join84}from"node:path";function isLocalInjectAlias(slug2){return LOCAL_PROVIDER_PREFIXES.some(prefix=>slug2.startsWith(prefix))}function kimiDataRoot(env){return env.KIMI_CODE_HOME||join84(env.HOME||env.USERPROFILE||homedir24(),".kimi-code")}function kimiTokenHeld(path3){try{let token=JSON.
|
|
7558
|
+
parse(readFileSync45(path3,"utf8"));if(!token||typeof token!="object")return!1;let{access_token:access2,refresh_token:refresh}=token;return!(access2===""&&refresh==="")}catch{return!1}}function kimiSignedIn(env){let credentials=join84(kimiDataRoot(env),"credentials");try{return readdirSync18(credentials).some(name=>KIMI_TOKEN_FILE.test(name)&&kimiTokenHeld(join84(credentials,name)))}catch{return!1}}function kimiSignInState(env){let credentials=join84(kimiDataRoot(env),"credentials"),names;try{names=
|
|
7559
|
+
readdirSync18(credentials)}catch(error62){return error62.code==="ENOENT"?"signed-out":"unknown"}return names.some(name=>KIMI_TOKEN_FILE.test(name)&&kimiTokenHeld(join84(credentials,name)))?"signed-in":"signed-out"}function kimiRemoveCredentials(env){let credentials=join84(kimiDataRoot(env),"credentials");for(let name of readdirSync18(credentials))KIMI_TOKEN_FILE.test(name)&&unlinkSync10(join84(credentials,name))}function kimiLoginFailure(output2){return/expired|timed out/i.test(output2)?"The Kim\
|
|
7556
7560
|
i sign-in code expired. Start sign-in again for a new code.":/denied|login cancelled/i.test(output2)?"Kimi sign-in was declined in the browser. Start sign-in again to try once more.":"Kimi sign-in did not finish. Check the server's connection, then try again."}function quoteToml2(value){return`"${value.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function quoteTomlKey(key2){return/^[A-Za-z0-9_-]+$/.test(key2)?key2:quoteToml2(key2)}function stripTomlLineComment(line3){let quote=null;for(let i2=0;i2<
|
|
7557
7561
|
line3.length;i2++){let c2=line3[i2];if(quote){if(quote==='"'&&c2==="\\"){i2+=1;continue}c2===quote&&(quote=null);continue}if(c2==="#")return line3.slice(0,i2);(c2==='"'||c2==="'")&&(quote=c2)}return line3}function takeTomlBasicEscape(text13,i2){let code=text13[i2+1];if(code===void 0)return{ok:!1};if(code==="u"){let hex3=text13.slice(i2+2,i2+6);if(!/^[0-9a-fA-F]{4}$/.test(hex3))return{ok:!1};let point3=parseInt(hex3,16);return point3>=55296&&point3<=57343?{ok:!1}:{ok:!0,value:String.fromCharCode(
|
|
7558
7562
|
point3),next:i2+6}}if(code==="U"){let hex3=text13.slice(i2+2,i2+10);if(!/^[0-9a-fA-F]{8}$/.test(hex3))return{ok:!1};let point3=parseInt(hex3,16);return point3>1114111||point3>=55296&&point3<=57343?{ok:!1}:{ok:!0,value:String.fromCodePoint(point3),next:i2+10}}let named2={b:"\b",t:" ",n:`
|
|
@@ -7575,16 +7579,16 @@ slice(table3.bodyStart,table3.end)),missing=rows.filter(row=>!keys.has(tomlRowKe
|
|
|
7575
7579
|
`;return`${before}${pad}${missing.join(`
|
|
7576
7580
|
`)}${after.startsWith(`
|
|
7577
7581
|
`)?"":`
|
|
7578
|
-
`}${after}`}function ensureKimiInjectAlias(modelId2,env=process.env){let inject=decodeInjectId(modelId2);if(!inject)return modelId2;let host2=localHost(inject.host);if(!host2)return modelId2;let alias=`${inject.host}/${inject.model.replace(/\//g,"-")}`,dataRoot=kimiDataRoot(env);
|
|
7582
|
+
`}${after}`}function ensureKimiInjectAlias(modelId2,env=process.env){let inject=decodeInjectId(modelId2);if(!inject)return modelId2;let host2=localHost(inject.host);if(!host2)return modelId2;let alias=`${inject.host}/${inject.model.replace(/\//g,"-")}`,dataRoot=kimiDataRoot(env);mkdirSync33(dataRoot,{recursive:!0});let path3=join84(dataRoot,"config.toml"),text13="";try{text13=readFileSync45(path3,"utf8")}catch{text13=""}let original=text13,providerHeading=`[providers.${inject.host}]`,modelHeading=`\
|
|
7579
7583
|
[models.${quoteTomlKey(alias)}]`,blocks=[];if(hasTomlTable(text13,providerHeading)||blocks.push([providerHeading,'type = "openai_legacy"',`base_url = ${quoteToml2(host2.baseUrl)}`,`api_key = ${quoteToml2(hostApiKey(host2,env))}`,""].join(`
|
|
7580
7584
|
`)),hasTomlTable(text13,modelHeading)?text13=patchTomlTable(text13,modelHeading,['protocol = "openai"',"max_context_size = 262144"]):blocks.push([modelHeading,`provider = ${quoteToml2(inject.host)}`,`model = ${quoteToml2(inject.model)}`,'protocol = "openai"',"max_context_size = 262144",""].join(`
|
|
7581
7585
|
`)),blocks.length){let prefix=text13&&!text13.endsWith(`
|
|
7582
7586
|
`)?`${text13}
|
|
7583
7587
|
|
|
7584
7588
|
`:text13?`${text13}
|
|
7585
|
-
`:"";
|
|
7586
|
-
`)}`)}else text13!==original&&
|
|
7587
|
-
function readKimiModelCatalog(env){let fixed=currentEngineCatalog("kimi"),dataRoot=kimiDataRoot(env),text13="";try{text13=
|
|
7589
|
+
`:"";writeFileSync19(path3,`${prefix}${blocks.join(`
|
|
7590
|
+
`)}`)}else text13!==original&&writeFileSync19(path3,text13);return alias}function applyKimiLocalModelEnv(env,modelId2){let inject=decodeInjectId(modelId2);if(!inject)return;let host2=localHost(inject.host);host2&&(env.KIMI_MODEL_NAME=inject.model,env.KIMI_MODEL_API_KEY=hostApiKey(host2,env),env.KIMI_MODEL_BASE_URL=host2.baseUrl,env.KIMI_MODEL_PROVIDER_TYPE="openai",env.KIMI_MODEL_DISPLAY_NAME=`${inject.model} (${host2.label})`)}function stripKimiModelEnv(env){for(let key2 of KIMI_MODEL_ENV)delete env[key2]}
|
|
7591
|
+
function readKimiModelCatalog(env){let fixed=currentEngineCatalog("kimi"),dataRoot=kimiDataRoot(env),text13="";try{text13=readFileSync45(join84(dataRoot,"config.toml"),"utf8")}catch{return fixed}let options2=fixed.options.map(o=>({...o})),seen=new Set(options2.map(o=>o.id)),current=null,flush=()=>{if(!current||!SLUG2.test(current.slug)||seen.has(current.slug)||isLocalInjectAlias(current.slug)){current=null;return}seen.add(current.slug),options2.push({id:current.slug,label:current.name||current.slug,
|
|
7588
7592
|
custom:!0}),current=null};for(let line3 of text13.split(/\r?\n/)){let stripped=line3.trim();if((stripped.startsWith("[model.")||stripped.startsWith("[models."))&&stripped.endsWith("]")){flush();let inner=stripped.replace(/^\[models?\./,"").slice(0,-1);inner.startsWith('"')&&inner.endsWith('"')&&(inner=inner.slice(1,-1)),current={slug:inner};continue}if(stripped.startsWith("[")){flush();continue}if(!stripped||stripped.startsWith("#")||!stripped.includes("="))continue;let eq=stripped.indexOf("="),
|
|
7589
7593
|
key2=stripped.slice(0,eq).trim(),value=stripped.slice(eq+1).trim();value.length>=2&&value.startsWith('"')&&value.endsWith('"')&&(value=value.slice(1,-1)),current&&(key2==="name"||key2==="label")&&value&&(current.name=value)}return flush(),{default:fixed.default,options:options2}}var SLUG2,LOCAL_PROVIDER_PREFIXES,KIMI_TOKEN_FILE,KIMI_DEVICE_SIGN_IN,KIMI_MODEL_ENV,support4,KimiAgentDriver,init_kimi=__esm({"server/drivers/acp/kimi.ts"(){"use strict";init_local_inject();init_core3();init_manifest();
|
|
7590
7594
|
init_schema2();SLUG2=ENGINE_MODEL_ID.kimi,LOCAL_PROVIDER_PREFIXES=LOCAL_HOSTS.map(host2=>`${host2.id}/`);KIMI_TOKEN_FILE=/^kimi-code(?:-env-[0-9a-f]+)?\.json$/;KIMI_DEVICE_SIGN_IN={provider:"kimi",product:"Kimi",account:"Kimi Code",homeEnv:"KIMI_CODE_HOME",homeDir:".kimi-code",loginArgs:["login"],install:"Install it with Moonshot's installer (https://code.kimi.com), or from Settings when this server has npm, then try again.",failure:kimiLoginFailure,signedIn:kimiSignedIn,signInState:kimiSignInState,
|
|
@@ -7592,21 +7596,21 @@ removeCredentials:kimiRemoveCredentials};KIMI_MODEL_ENV=["KIMI_MODEL_NAME","KIMI
|
|
|
7592
7596
|
darwin:"curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash",linux:"curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash",win32:"irm https://code.kimi.com/kimi-code/install.ps1 | iex"},npmPackage:"@moonshot-ai/kimi-code",docsUrl:"https://moonshotai.github.io/kimi-code/en/guides/getting-started.html",signInCommand:"kimi login"},deviceSignIn:KIMI_DEVICE_SIGN_IN,resolveTurnModel:(model,env)=>model&&ensureKimiInjectAlias(model,env),spawnArgs:(_config,turn)=>{let model=turn.model;return[
|
|
7593
7597
|
...model?["-m",model]:[],"acp"]},transformEnv:env=>{delete env.MOONSHOT_API_KEY,delete env.KIMI_API_KEY,stripKimiModelEnv(env)},applyTurnEnv:(env,{requestedModel})=>{applyKimiLocalModelEnv(env,requestedModel)},pickAuthMethod:()=>null,authFailure:"continue",isAuthenticated:kimiSignedIn,buildPromptText:turn=>turn.system?`${turn.system}
|
|
7594
7598
|
|
|
7595
|
-
${turn.text}`:turn.text},KimiAgentDriver=createAcpDriver(support4)}});import{existsSync as
|
|
7596
|
-
env){let inject=decodeInjectId(modelId2);if(!inject)return modelId2;let host2=localHost(inject.host);if(!host2)return modelId2;let id=droidInjectId(inject.host,inject.model),dir=
|
|
7597
|
-
[],match=custom2.find(row=>row.id===id||row.model===inject.model&&row.baseUrl===host2.baseUrl);return match?(match.id||(match.id=id,settings2.customModels=custom2,
|
|
7598
|
-
`)),match.id):(custom2.push({id,model:inject.model,displayName:`${inject.model} (${host2.label})`,baseUrl:host2.baseUrl,apiKey:hostApiKey(host2,env),provider:"generic-chat-completion-api"}),settings2.customModels=custom2,
|
|
7599
|
-
`),id)}function applyDroidLocalAuthEnv(env,modelId2){decodeInjectId(modelId2)&&(env.FACTORY_API_KEY?.trim()||authFilePaths(env).some(
|
|
7599
|
+
${turn.text}`:turn.text},KimiAgentDriver=createAcpDriver(support4)}});import{existsSync as existsSync33,mkdirSync as mkdirSync34,readFileSync as readFileSync46,writeFileSync as writeFileSync20}from"node:fs";import{join as join85}from"node:path";function authFilePaths(env){let home2=env.FACTORY_HOME_OVERRIDE||userHome(env);return AUTH_FILES.map(name=>join85(home2,".factory",name))}function droidInjectId(host2,model){let safe=`${host2}-${model}`.replace(/[^a-zA-Z0-9._+-]+/g,"-").replace(/-+/g,"-");return`${INJECT_ID_PREFIX}${safe}`}function ensureDroidInjectModel(modelId2,env=process.
|
|
7600
|
+
env){let inject=decodeInjectId(modelId2);if(!inject)return modelId2;let host2=localHost(inject.host);if(!host2)return modelId2;let id=droidInjectId(inject.host,inject.model),dir=join85(env.FACTORY_HOME_OVERRIDE||userHome(env),".factory");mkdirSync34(dir,{recursive:!0});let path3=join85(dir,"settings.json"),settings2={};try{settings2=JSON.parse(readFileSync46(path3,"utf8"))}catch(error62){if(existsSync33(path3))throw error62}let custom2=Array.isArray(settings2.customModels)?[...settings2.customModels]:
|
|
7601
|
+
[],match=custom2.find(row=>row.id===id||row.model===inject.model&&row.baseUrl===host2.baseUrl);return match?(match.id||(match.id=id,settings2.customModels=custom2,writeFileSync20(path3,`${JSON.stringify(settings2,null,2)}
|
|
7602
|
+
`)),match.id):(custom2.push({id,model:inject.model,displayName:`${inject.model} (${host2.label})`,baseUrl:host2.baseUrl,apiKey:hostApiKey(host2,env),provider:"generic-chat-completion-api"}),settings2.customModels=custom2,writeFileSync20(path3,`${JSON.stringify(settings2,null,2)}
|
|
7603
|
+
`),id)}function applyDroidLocalAuthEnv(env,modelId2){decodeInjectId(modelId2)&&(env.FACTORY_API_KEY?.trim()||authFilePaths(env).some(existsSync33)||(env.FACTORY_API_KEY="openmausbot-local"))}function readSettings(env){return JSON.parse(readFileSync46(join85(env.FACTORY_HOME_OVERRIDE||userHome(env),".factory","settings.json"),"utf8"))}async function resolveModels(env){let catalog=MODELS2;try{let settings2=readSettings(env),custom2=(settings2.customModels??[]).flatMap(m3=>{if(m3.id?.startsWith(INJECT_ID_PREFIX))
|
|
7600
7604
|
return[];let id=m3.id||(m3.model?`custom:${m3.model}`:"");return id?[{id,label:m3.displayName||m3.model||id,custom:!0}]:[]}),merged2=[...custom2,...MODELS2.options.filter(o=>!custom2.some(c2=>c2.id===o.id))],rank=new Map((settings2.modelFavorites??[]).map((id,i2)=>[id,i2])),options2=merged2.sort((a2,b3)=>(rank.get(a2.id)??1/0)-(rank.get(b3.id)??1/0)),configured=settings2.sessionDefaultSettings?.model,fallback=options2[0]?.id??MODELS2.default;catalog={default:configured&&options2.some(o=>o.id===configured)?
|
|
7601
7605
|
configured:fallback,options:options2}}catch{}return mergeLocalInject(catalog,env)}async function applySetting(request2,method,params,what){try{await request2(method,params)}catch(e){throw new Error(`Droid rejected ${what} via ${method}: ${e.message}. Check that \`droid\` is current (0.196.0+ supports it) and that this account can use that value.`)}}var AUTH_FILES,INJECT_ID_PREFIX,MODE_DEFAULT,MODE_FULL_AUTO,MODELS2,support5,DroidAgentDriver,init_droid=__esm({"server/drivers/acp/droid.ts"(){"use \
|
|
7602
7606
|
strict";init_env_path();init_local_inject();init_core3();AUTH_FILES=["auth.v2.file","auth.v2.loginkeychain","auth.v2.keyring"];INJECT_ID_PREFIX="custom:openmausbot-";MODE_DEFAULT="normal",MODE_FULL_AUTO="auto-high",MODELS2={default:"claude-opus-5",options:[{id:"auto",label:"Auto (Factory picks)"},{id:"claude-opus-5",label:"Claude Opus 5"},{id:"claude-sonnet-5",label:"Claude Sonnet 5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"},{id:"gpt-5.6-sol",label:"GPT-5.6 Sol"},{id:"gpt-5.6-te\
|
|
7603
7607
|
rra",label:"GPT-5.6 Terra"},{id:"gemini-3.1-pro-preview",label:"Gemini 3.1 Pro"},{id:"glm-5.2",label:"GLM 5.2"},{id:"kimi-k3",label:"Kimi K3"},{id:"grok-4.6",label:"Grok 4.6"}]},support5={driverKind:"droidAgent",displayName:"Droid",models:MODELS2,defaultCli:"droid",nativeSource:"droid.acp",loginNote:"Droid CLI is not signed in \u2014 run `droid` once and log in, or set FACTORY_API_KEY",install:{command:{darwin:"curl -fsSL https://app.factory.ai/cli | sh",linux:"curl -fsSL https://app.factory.ai/\
|
|
7604
|
-
cli | sh",win32:"irm https://app.factory.ai/cli/windows | iex"},docsUrl:"https://docs.factory.ai/droid-cli/quickstart",signInCommand:"droid"},spawnArgs:()=>["exec","-o","acp"],credentialEnv:["FACTORY_API_KEY"],pickAuthMethod:()=>null,authFailure:"continue",isAuthenticated:env=>authFilePaths(env).some(
|
|
7608
|
+
cli | sh",win32:"irm https://app.factory.ai/cli/windows | iex"},docsUrl:"https://docs.factory.ai/droid-cli/quickstart",signInCommand:"droid"},spawnArgs:()=>["exec","-o","acp"],credentialEnv:["FACTORY_API_KEY"],pickAuthMethod:()=>null,authFailure:"continue",isAuthenticated:env=>authFilePaths(env).some(existsSync33)||!!env.FACTORY_API_KEY,resolveModels,resolveTurnModel:(model,env)=>model&&ensureDroidInjectModel(model,env),applyTurnEnv:(env,{requestedModel})=>{applyDroidLocalAuthEnv(env,requestedModel)},
|
|
7605
7609
|
async configureSession({request:request2,sessionId,config:config3,turn}){let modeId=config3.fullAuto?MODE_FULL_AUTO:MODE_DEFAULT;await applySetting(request2,"session/set_mode",{sessionId,modeId},`autonomy mode "${modeId}"`);let modelId2=turn.model??MODELS2.default;await applySetting(request2,"session/set_model",{sessionId,modelId:modelId2},`model "${modelId2}"`)},buildPromptText:turn=>turn.system?`${turn.system}
|
|
7606
7610
|
|
|
7607
|
-
${turn.text}`:turn.text},DroidAgentDriver=createAcpDriver(support5)}});function deletesAcpSessions(initialized){return!!initialized?.agentCapabilities?.sessionCapabilities?.delete}async function deleteAcpSessions(request2,sessionIds){let ids=[...new Set(sessionIds)],answers=await Promise.allSettled(ids.map(sessionId=>request2("session/delete",{sessionId})));return ids.filter((_3,index2)=>answers[index2]?.status==="fulfilled")}var init_session_delete=__esm({"server/drivers/acp/session-delete.ts"(){"use strict"}});import{mkdtemp as mkdtemp3,rm as rm5}from"node:fs/promises";import{tmpdir as tmpdir12}from"node:os";import{join as
|
|
7611
|
+
${turn.text}`:turn.text},DroidAgentDriver=createAcpDriver(support5)}});function deletesAcpSessions(initialized){return!!initialized?.agentCapabilities?.sessionCapabilities?.delete}async function deleteAcpSessions(request2,sessionIds){let ids=[...new Set(sessionIds)],answers=await Promise.allSettled(ids.map(sessionId=>request2("session/delete",{sessionId})));return ids.filter((_3,index2)=>answers[index2]?.status==="fulfilled")}var init_session_delete=__esm({"server/drivers/acp/session-delete.ts"(){"use strict"}});import{mkdtemp as mkdtemp3,rm as rm5}from"node:fs/promises";import{tmpdir as tmpdir12}from"node:os";import{join as join86}from"node:path";import{StringDecoder}from"node:string_decoder";function record7(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)?value:void 0}async function stopDiscovery(child,graceMs){if(!child)return!0;if(graceMs!==void 0&&child.exitCode===null&&child.signalCode===null){let exited=new Promise(resolve35=>child.once("exit",()=>resolve35()));try{child.
|
|
7608
7612
|
stdin.end()}catch{}await Promise.race([exited,new Promise(resolve35=>setTimeout(resolve35,graceMs).unref())])}return killCliTree(child,process.platform==="win32"?5e3:500)}function usableDiscoveredId(id){return typeof id=="string"&&id.length<=200&&!id.includes("..")&&/^[A-Za-z0-9][A-Za-z0-9 ._():[\]{}=,@+/:-]*$/.test(id)}function usableDiscoveredLabel(label2){if(typeof label2!="string"||label2.length>200)return!1;for(let char of label2){let code=char.codePointAt(0);if(code<32||code>=127&&code<=159||
|
|
7609
|
-
BIDI_CONTROLS.has(code))return!1}return!0}function resolveCustomAcpModels(env,config3,_instanceId){return discoverAcpModels(env,config3.cli,[],{passthrough:AGENT_DEFAULT,custom:!0})}async function discoverAcpModels(env,cli,args,discovery={}){let cwd=await mkdtemp3(
|
|
7613
|
+
BIDI_CONTROLS.has(code))return!1}return!0}function resolveCustomAcpModels(env,config3,_instanceId){return discoverAcpModels(env,config3.cli,[],{passthrough:AGENT_DEFAULT,custom:!0})}async function discoverAcpModels(env,cli,args,discovery={}){let cwd=await mkdtemp3(join86(tmpdir12(),"omb-acp-models-")),child,globalTimer,pending=new Map,failure2,sequence=0,updateSequence=0,sessionId,initialized,latestUpdate,outputBytes=0,buffer="",decoder4=new StringDecoder("utf8"),catalog,thrown,fail3=message5=>{
|
|
7610
7614
|
failure2??=new Error(message5);for(let entry of pending.values())clearTimeout(entry.timer),entry.reject(failure2);pending.clear()},count5=chunk=>(outputBytes+=chunk.length,outputBytes>MAX_OUTPUT_BYTES&&fail3("ACP model discovery exceeded its output limit."),!failure2),send2=message5=>{failure2||child?.stdin.write(`${JSON.stringify(message5)}
|
|
7611
7615
|
`)},receive=line3=>{let parsed;try{parsed=JSON.parse(line3)}catch{return}let message5=record7(parsed);if(!message5)return;if(typeof message5.method=="string"&&message5.id!==void 0){send2(message5.method==="session/request_permission"?{jsonrpc:"2.0",id:message5.id,result:{outcome:{outcome:"cancelled"}}}:{jsonrpc:"2.0",id:message5.id,error:{code:-32601,message:"Unavailable during model discovery"}});return}if(message5.method==="session/update"){let params=record7(message5.params),update=record7(params?.
|
|
7612
7616
|
update);sessionId&¶ms?.sessionId===sessionId&&update?.sessionUpdate==="config_option_update"&&(latestUpdate=update,updateSequence++);return}if(typeof message5.id!="number")return;let entry=pending.get(message5.id);if(entry)if(pending.delete(message5.id),clearTimeout(entry.timer),message5.error!==void 0){let error62=record7(message5.error);entry.reject(new AcpDiscoveryRpcError(error62?.code,typeof error62?.message=="string"?error62.message:""))}else entry.resolve(message5.result)},request2=(method,params)=>{
|
|
@@ -7651,28 +7655,28 @@ id==="fast"),wantsFast=/-fast$/i.test(turn.model),wanted=fastOption&&wantsFast?t
|
|
|
7651
7655
|
find(m3=>m3.modelId===currentModelId)?.name??currentModelId;notice(`Cursor did not accept ${turn.model} in this session, so it runs ${running4??"its default model"}. Choose another model for this bot to stop seeing this.`);return}throw new Error(`Cursor rejected model "${turn.model}" (sent as "${modelId2}") via session/set_model: ${err.message}. Check that \`cursor-agent\` is current and that this account can use that model.`)}fastOption&&await setCursorFast(request2,sessionId,wantsFast)},buildPromptText:turn=>turn.
|
|
7652
7656
|
system?`${turn.system}
|
|
7653
7657
|
|
|
7654
|
-
${turn.text}`:turn.text});CursorAgentDriver=createCursorAgentDriver()}});import{basename as basename16,dirname as dirname33,extname as extname3,join as
|
|
7655
|
-
ATTACHMENTS_MAX_BYTES,ATTACHMENT_PARTIAL_MAX_AGE_MS,STREAM_RESERVATION_INCREMENT_BYTES,IMAGE_MIMES,FILE_MIMES,ATTACHMENT_CLEAR_MIN_AGE_MS,KNOWN_ATTACHMENT_EXTENSIONS,init_attachments=__esm({"server/attachments.ts"(){"use strict";init_upload_limits();init_config3();init_plan();init_upload_limits();ATTACHMENTS_DIR=
|
|
7658
|
+
${turn.text}`:turn.text});CursorAgentDriver=createCursorAgentDriver()}});import{basename as basename16,dirname as dirname33,extname as extname3,join as join87,resolve as resolve27}from"node:path";function attachmentsMaxBytes(env=process.env){let raw=env.OMB_ATTACHMENTS_MAX_BYTES?.trim(),parsed=raw?Number(raw):NaN;return Number.isSafeInteger(parsed)&&parsed>0?parsed:env.OMB_CLOUD_ROLE==="home"||env.OMB_CLOUD_ROLE==="team"?CLOUD_HOME_ATTACHMENTS_MAX_BYTES:DEFAULT_ATTACHMENTS_MAX_BYTES}var ATTACHMENTS_DIR,IMAGE_MAX_BYTES,DEFAULT_ATTACHMENTS_MAX_BYTES,CLOUD_HOME_ATTACHMENTS_MAX_BYTES,
|
|
7659
|
+
ATTACHMENTS_MAX_BYTES,ATTACHMENT_PARTIAL_MAX_AGE_MS,STREAM_RESERVATION_INCREMENT_BYTES,IMAGE_MIMES,FILE_MIMES,ATTACHMENT_CLEAR_MIN_AGE_MS,KNOWN_ATTACHMENT_EXTENSIONS,init_attachments=__esm({"server/attachments.ts"(){"use strict";init_upload_limits();init_config3();init_plan();init_upload_limits();ATTACHMENTS_DIR=join87(DATA_DIR,"attachments"),IMAGE_MAX_BYTES=10*1024*1024,DEFAULT_ATTACHMENTS_MAX_BYTES=512*1024*1024,CLOUD_HOME_ATTACHMENTS_MAX_BYTES=8*1024*1024*1024;ATTACHMENTS_MAX_BYTES=attachmentsMaxBytes(),
|
|
7656
7660
|
ATTACHMENT_PARTIAL_MAX_AGE_MS=3600*1e3,STREAM_RESERVATION_INCREMENT_BYTES=1024*1024,IMAGE_MIMES={"image/png":".png","image/jpeg":".jpg","image/gif":".gif","image/webp":".webp"},FILE_MIMES={"video/mp4":".mp4","video/webm":".webm","video/quicktime":".mov","audio/opus":".opus","audio/ogg":".ogg","audio/mpeg":".mp3","audio/mp4":".m4a","audio/x-m4a":".m4a","audio/aac":".aac","audio/wav":".wav","audio/x-wav":".wav","audio/wave":".wav","audio/flac":".flac","audio/x-flac":".flac","audio/webm":".webm","t\
|
|
7657
7661
|
ext/plain":".txt","text/markdown":".md","text/csv":".csv","text/tab-separated-values":".tsv","application/json":".json","application/pdf":".pdf","application/rtf":".rtf","text/rtf":".rtf","application/msword":".doc","application/vnd.openxmlformats-officedocument.wordprocessingml.document":".docx","application/vnd.ms-excel":".xls","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":".xlsx","application/vnd.ms-powerpoint":".ppt","application/vnd.openxmlformats-officedocument.presen\
|
|
7658
7662
|
tationml.presentation":".pptx","application/vnd.oasis.opendocument.text":".odt","application/vnd.oasis.opendocument.spreadsheet":".ods","application/vnd.oasis.opendocument.presentation":".odp"},ATTACHMENT_CLEAR_MIN_AGE_MS=600*1e3,KNOWN_ATTACHMENT_EXTENSIONS=Array.from(new Set([...Object.values(IMAGE_MIMES),...Object.values(FILE_MIMES)]))}});function openCodeModelId(value){let id=value.trim();return OPENCODE_MODEL.test(id)&&!id.endsWith("/")?id:null}function typedOpenCodeModel(savedId){if(!savedId?.startsWith(TYPED_PREFIX))return null;let id=savedId.slice(TYPED_PREFIX.length);return openCodeModelId(id)===id?id:null}var TYPED_PREFIX,OPENCODE_MODEL,init_opencode_model_id=__esm({"shared/opencode-model-id.ts"(){"use strict";TYPED_PREFIX="typed::",OPENCODE_MODEL=/^[A-Za-z0-9][\w.-]{0,63}\/[A-Za-z0-9][\w.:@+/-]{0,199}$/u}});function record8(value){return value&&typeof value=="object"&&!Array.isArray(value)?value:{}}function declareOpenCodeModels(env,byProvider){let declared=Object.entries(byProvider).filter(([,ids])=>ids.length);if(!declared.length)return;let config3={};if(env.OPENCODE_CONFIG_CONTENT?.trim())try{let parsed=JSON.parse(env.OPENCODE_CONFIG_CONTENT);if(!parsed||typeof parsed!="object"||Array.isArray(parsed))return;config3=parsed}catch{return}let providers={...record8(config3.provider)};for(let[providerId,
|
|
7659
7663
|
ids]of declared){let provider=record8(providers[providerId]);providers[providerId]={...provider,models:{...Object.fromEntries(ids.map(id=>[id,{}])),...record8(provider.models)}}}env.OPENCODE_CONFIG_CONTENT=JSON.stringify({...config3,provider:providers})}function declareTypedOpenCodeModel(env,savedId){let model=typedOpenCodeModel(savedId);if(!model)return;let separator=model.indexOf("/");return declareOpenCodeModels(env,{[model.slice(0,separator)]:[model.slice(separator+1)]}),model}var init_opencode_typed_model=__esm(
|
|
7660
|
-
{"server/drivers/acp/opencode-typed-model.ts"(){"use strict";init_opencode_model_id()}});import{mkdirSync as
|
|
7661
|
-
(memo2.providers[provider]={checkedAt:entry.checkedAt,models:models2})}for(let[instanceId,at2]of Object.entries(record9(raw.refreshedAt)))typeof at2=="number"&&Number.isFinite(at2)&&(memo2.refreshedAt[instanceId]=at2)}catch{}return memo2}function save(){try{
|
|
7664
|
+
{"server/drivers/acp/opencode-typed-model.ts"(){"use strict";init_opencode_model_id()}});import{mkdirSync as mkdirSync35,readFileSync as readFileSync47}from"node:fs";import{dirname as dirname34,join as join88}from"node:path";function load(){if(memo2)return memo2;memo2={providers:{},refreshedAt:{}};try{let raw=record9(JSON.parse(readFileSync47(storePath(),"utf8")));for(let[provider,value]of Object.entries(record9(raw.providers))){let entry=record9(value),models2=Array.isArray(entry.models)?entry.models.filter(id=>typeof id=="string"):[];typeof entry.checkedAt=="number"&&models2.length&&
|
|
7665
|
+
(memo2.providers[provider]={checkedAt:entry.checkedAt,models:models2})}for(let[instanceId,at2]of Object.entries(record9(raw.refreshedAt)))typeof at2=="number"&&Number.isFinite(at2)&&(memo2.refreshedAt[instanceId]=at2)}catch{}return memo2}function save(){try{mkdirSync35(dirname34(storePath()),{recursive:!0}),writeFileAtomic(storePath(),JSON.stringify(load()),{durable:!1})}catch{}}function openCodeCatalogRefreshedAt(instanceId){return load().refreshedAt[instanceId]??0}function markOpenCodeCatalogRefreshed(instanceId,at2){
|
|
7662
7666
|
load().refreshedAt[instanceId]=at2,save()}async function readListing(list5,key2,fetcher){let response=await fetcher(list5.url,{headers:{accept:"application/json",authorization:`Bearer ${key2}`,"user-agent":"Limix Bot"},redirect:"error",signal:AbortSignal.timeout(FETCH_TIMEOUT_MS)});if(!response.ok)throw response.body?.cancel().catch(()=>{}),new Error(`HTTP ${response.status}`);if(Number(response.headers.get("content-length"))>MAX_BYTES3)throw response.body?.cancel().catch(()=>{}),new Error("the \
|
|
7663
7667
|
listing is too large");let text13=await response.text();if(text13.length>MAX_BYTES3)throw new Error("the listing is too large");let data=record9(JSON.parse(text13)).data;if(!Array.isArray(data))throw new Error("the listing has no data");let ids=new Set;for(let value of data){let entry=record9(value);if(!(typeof entry.id!="string"||list5.keep&&!list5.keep(entry))&&(openCodeModelId(`${list5.provider}/${entry.id}`)===`${list5.provider}/${entry.id}`&&ids.add(entry.id),ids.size>=MAX_MODELS2))break}return[
|
|
7664
7668
|
...ids].sort()}async function refreshLiveModelLists(env,options2={}){let store2=load(),changed2=!1;await Promise.all((options2.lists??OPENCODE_LIVE_MODEL_LISTS).map(async list5=>{let key2=env[list5.env]?.trim();if(key2)try{let models2=await readListing(list5,key2,options2.fetch??fetch);if(!models2.length)throw new Error("the listing names no model");store2.providers[list5.provider]={checkedAt:(options2.now??Date.now)(),models:models2},changed2=!0}catch(error62){console.warn(`[opencode] could not\
|
|
7665
7669
|
read ${list5.provider}'s model list (${error62 instanceof Error?error62.message:String(error62)}); keeping the last one`)}})),changed2&&save()}function declareLiveOpenCodeModels(env,lists2=OPENCODE_LIVE_MODEL_LISTS){let store2=load();declareOpenCodeModels(env,Object.fromEntries(lists2.flatMap(list5=>{let models2=store2.providers[list5.provider]?.models;return env[list5.env]?.trim()&&models2?.length?[[list5.provider,models2]]:[]})))}function keepOpenCodeModelsFresh(instance,instanceId,schedule={}){
|
|
7666
7670
|
let now=schedule.now??Date.now,disposed=!1,refreshWhenDue=()=>{!disposed&&now()-openCodeCatalogRefreshedAt(instanceId)>=(schedule.everyMs??OPENCODE_MODEL_REFRESH_MS)&&instance.refreshModels?.().catch(()=>{})},timer2=setInterval(refreshWhenDue,schedule.checkMs??REFRESH_CHECK_MS);timer2.unref?.(),(instance.startupModelRefresh??Promise.resolve()).then(refreshWhenDue,refreshWhenDue);let dispose=instance.dispose.bind(instance);instance.dispose=async()=>{disposed=!0,clearInterval(timer2),await dispose()}}
|
|
7667
7671
|
var record9,OPENCODE_LIVE_MODEL_LISTS,OPENCODE_MODEL_REFRESH_MS,REFRESH_CHECK_MS,FETCH_TIMEOUT_MS,MAX_BYTES3,MAX_MODELS2,memo2,storePath,init_opencode_model_refresh=__esm({"server/drivers/acp/opencode-model-refresh.ts"(){"use strict";init_opencode_model_id();init_atomic();init_config3();init_opencode_typed_model();record9=value=>value&&typeof value=="object"&&!Array.isArray(value)?value:{},OPENCODE_LIVE_MODEL_LISTS=[{provider:"venice",env:"VENICE_API_KEY",url:"https://api.venice.ai/api/v1/models\
|
|
7668
|
-
?type=text",keep:entry=>record9(record9(entry.model_spec).capabilities).supportsE2EE!==!0}],OPENCODE_MODEL_REFRESH_MS=180*6e4,REFRESH_CHECK_MS=10*6e4,FETCH_TIMEOUT_MS=1e4,MAX_BYTES3=4*1024*1024,MAX_MODELS2=2e3,memo2=null,storePath=()=>
|
|
7669
|
-
ts"(){"use strict"}});import{execFile as execFile14}from"node:child_process";import{existsSync as
|
|
7672
|
+
?type=text",keep:entry=>record9(record9(entry.model_spec).capabilities).supportsE2EE!==!0}],OPENCODE_MODEL_REFRESH_MS=180*6e4,REFRESH_CHECK_MS=10*6e4,FETCH_TIMEOUT_MS=1e4,MAX_BYTES3=4*1024*1024,MAX_MODELS2=2e3,memo2=null,storePath=()=>join88(DATA_DIR,"providers","opencode","live-models.json")}});function openCodePromptUnreachedModel(error62){let value=error62&&typeof error62=="object"?error62:{};if(value.code!==-32603)return!1;let data=value.data&&typeof value.data=="object"&&!Array.isArray(value.data)?value.data:{},text13=[value.message,data.message,data.details].filter(part=>typeof part=="string").join(" ");return/\bECONNREFUSED\b|\bConnectionRefused\b|\bCannot connect to API: Unable to connect\b/u.test(text13)}var init_opencode_unreached=__esm({"server/drivers/acp/opencode-unreached.\
|
|
7673
|
+
ts"(){"use strict"}});import{execFile as execFile14}from"node:child_process";import{existsSync as existsSync34,mkdirSync as mkdirSync36,readFileSync as readFileSync48,rmSync as rmSync25,writeFileSync as writeFileSync21}from"node:fs";import{join as join89}from"node:path";function labelForModel(id){return titleCaseModelId(id,/[-_.]+/)}function providerLabel(id){return id==="opencode"?"Zen":id==="opencode-go"?"Go":id==="openrouter"?"OpenRouter":labelForModel(id)}function validModelSlug(value){let separator=value.indexOf(
|
|
7670
7674
|
"/");return separator<=0||separator>=value.length-1||/\s/u.test(value)?!1:[...value].every(character=>(character.codePointAt(0)??0)>31)}function catalogFromOpenCodeSession(result2){let configOptions2=result2?.configOptions,model=Array.isArray(configOptions2)?configOptions2.find(option=>option?.id==="model"&&option?.type==="select"):null,ids=offeredModels(result2,"model");if(!model||!ids.length)return null;let names=new Map,visit4=entries2=>{if(Array.isArray(entries2))for(let entry of entries2)typeof entry?.
|
|
7671
7675
|
value=="string"&&typeof entry.name=="string"?names.set(entry.value,entry.name):Array.isArray(entry?.options)&&visit4(entry.options)};visit4(model.options);let options2=[...new Set(ids)].filter(validModelSlug).map(id=>{let separator=id.indexOf("/"),raw=names.get(id)?.trim()??"",name=(raw.includes("/")?raw.slice(raw.indexOf("/")+1):raw).trim()||labelForModel(id.slice(separator+1));return{id,label:`${providerLabel(id.slice(0,separator))} \xB7 ${name}`}});return options2.length?{options:options2,current:typeof model.
|
|
7672
|
-
currentValue=="string"?model.currentValue:null}:null}function runGit(directory,args){let env=Object.fromEntries(Object.entries(process.env).filter(([key2])=>!key2.startsWith("GIT_")));return new Promise((resolveRun,rejectRun)=>{execFile14("git",["-c","user.name=Limix","-c","user.email=model-discovery@openmaus.invalid","-c","commit.gpgsign=false","-c",`core.hooksPath=${
|
|
7673
|
-
/dev/null",GIT_CONFIG_NOSYSTEM:"1"},timeout:1e4,windowsHide:!0},error62=>{error62?rejectRun(error62):resolveRun()})})}function discoveryDirectory(){return discoveryFolder??=(async()=>{let directory=
|
|
7674
|
-
["commit","-q","--allow-empty","--no-verify","-m","Limix model discovery"]),
|
|
7675
|
-
`)}catch{}return directory})(),discoveryFolder}function surveyOpenCodeEfforts(request2,session,budgetMs=EFFORT_SURVEY_MS){return surveyModelVariants(request2,session,budgetMs)}function readProbeLedger(cwd){try{let ledger=JSON.parse(
|
|
7676
|
+
currentValue=="string"?model.currentValue:null}:null}function runGit(directory,args){let env=Object.fromEntries(Object.entries(process.env).filter(([key2])=>!key2.startsWith("GIT_")));return new Promise((resolveRun,rejectRun)=>{execFile14("git",["-c","user.name=Limix","-c","user.email=model-discovery@openmaus.invalid","-c","commit.gpgsign=false","-c",`core.hooksPath=${join89(directory,".git","no-hooks")}`,"-c","core.fsmonitor=false",...args],{cwd:directory,env:{...env,GIT_TERMINAL_PROMPT:"0",GIT_CONFIG_GLOBAL:"\
|
|
7677
|
+
/dev/null",GIT_CONFIG_NOSYSTEM:"1"},timeout:1e4,windowsHide:!0},error62=>{error62?rejectRun(error62):resolveRun()})})}function discoveryDirectory(){return discoveryFolder??=(async()=>{let directory=join89(DATA_DIR,"providers","opencode","discovery");mkdirSync36(directory,{recursive:!0});let marker=join89(directory,".openmaus-project");if(!existsSync34(marker))try{rmSync25(directory,{recursive:!0,force:!0}),mkdirSync36(directory,{recursive:!0}),await runGit(directory,["init","-q"]),await runGit(directory,
|
|
7678
|
+
["commit","-q","--allow-empty","--no-verify","-m","Limix model discovery"]),writeFileSync21(marker,`OpenCode files this folder's sessions under its own project.
|
|
7679
|
+
`)}catch{}return directory})(),discoveryFolder}function surveyOpenCodeEfforts(request2,session,budgetMs=EFFORT_SURVEY_MS){return surveyModelVariants(request2,session,budgetMs)}function readProbeLedger(cwd){try{let ledger=JSON.parse(readFileSync48(probeLedgerPath(cwd),"utf8"));return ledger&&typeof ledger=="object"&&!Array.isArray(ledger)?ledger:{}}catch{return{}}}function changeProbeLedger(cwd,change){let ledger=readProbeLedger(cwd);change(ledger);try{writeFileAtomic(probeLedgerPath(cwd),JSON.stringify(
|
|
7676
7680
|
ledger),{durable:!1})}catch{}}async function deleteProbeSessions(request2,cwd,opened,timeoutMs){let abandonedBefore=Date.now()-2*timeoutMs,abandoned=Object.entries(readProbeLedger(cwd)).filter(([,openedAt])=>openedAt<abandonedBefore).map(([sessionId])=>sessionId),deleted=await deleteAcpSessions(request2,[...opened,...abandoned]);deleted.length&&changeProbeLedger(cwd,ledger=>{for(let sessionId of deleted)delete ledger[sessionId]})}async function probeOpenCodeSession(cli,environment,timeoutMs=DISCOVERY_TIMEOUT_MS2,settleMs=0,allowEnv=[]){
|
|
7677
7681
|
let cwd=await discoveryDirectory(),deadline=Date.now()+timeoutMs;return new Promise((resolve35,reject)=>{let child;try{child=spawnCli(cli,["acp"],{cwd,env:environment,stdio:["pipe","pipe","pipe"],box:{allowEnv}})}catch(error62){reject(error62);return}let settled=!1,listed2,buffer="",nextId=0,pending=new Map,write=message5=>{try{child.stdin.write(`${JSON.stringify(message5)}
|
|
7678
7682
|
`)}catch{}},finish=(error62,value)=>{if(settled)return;settled=!0,clearTimeout(timer2);try{child.stdin.end()}catch{}killCliTree(child);for(let waiter of pending.values())waiter.reject(new Error("OpenCode closed"));pending.clear();let result2=value??listed2;result2?resolve35(result2):reject(error62??new Error("OpenCode did not list its models"))},timer2=setTimeout(()=>finish(Object.assign(new Error("OpenCode did not list its models in time"),{timedOut:!0})),timeoutMs);timer2.unref?.(),child.on("e\
|
|
@@ -7681,7 +7685,7 @@ rror",error62=>finish(error62)),child.on("close",code=>finish(new Error(`OpenCod
|
|
|
7681
7685
|
ed")),{code:message5.error.code,data:message5.error.data})):waiter.resolve(message5.result))}});let request2=(method,params)=>new Promise((resolveRequest,rejectRequest)=>{if(settled){rejectRequest(new Error("OpenCode closed"));return}let id=++nextId;pending.set(id,{resolve:resolveRequest,reject:rejectRequest}),write({jsonrpc:"2.0",id,method,params})}),deletesSessions=!1,opened=[],openSession=async()=>{let session=await request2("session/new",{cwd,mcpServers:[]}),sessionId=session?.sessionId;return deletesSessions&&
|
|
7682
7686
|
typeof sessionId=="string"&&(opened.push(sessionId),changeProbeLedger(cwd,ledger=>{ledger[sessionId]=Date.now()})),session},cleanUp=()=>deletesSessions?deleteProbeSessions(request2,cwd,opened,timeoutMs):Promise.resolve();(async()=>{let initialized=await request2("initialize",{protocolVersion:1,clientInfo:{name:"openmausbot",version:"0.0.0"},clientCapabilities:{fs:{readTextFile:!1,writeTextFile:!1},terminal:!1}});deletesSessions=deletesAcpSessions(initialized);let session=await openSession();listed2=
|
|
7683
7687
|
{session,efforts:new Map};let budget=Math.min(EFFORT_SURVEY_MS,deadline-Date.now()-1e3),efforts=await surveyOpenCodeEfforts(request2,session,budget);if(!settleMs)return{session,efforts};let wait2=Math.min(settleMs,timeoutMs-2e3)-(Date.now()-(deadline-timeoutMs));wait2>0&&await new Promise(resolveWait=>setTimeout(resolveWait,wait2));let later=await openSession();return{session:catalogFromOpenCodeSession(later)?later:session,efforts}})().then(result2=>(listed2=result2,cleanUp().then(()=>finish(null,
|
|
7684
|
-
result2))),error62=>cleanUp().then(()=>finish(error62)))})}var DISCOVERY_TIMEOUT_MS2,EFFORT_SURVEY_MS,discoveryFolder,probeLedgerPath,init_opencode_probe=__esm({"server/drivers/acp/opencode-probe.ts"(){"use strict";init_atomic();init_config3();init_contracts();init_procs();init_config_options();init_session_delete();DISCOVERY_TIMEOUT_MS2=2e4,EFFORT_SURVEY_MS=8e3;discoveryFolder=null;probeLedgerPath=cwd=>
|
|
7688
|
+
result2))),error62=>cleanUp().then(()=>finish(error62)))})}var DISCOVERY_TIMEOUT_MS2,EFFORT_SURVEY_MS,discoveryFolder,probeLedgerPath,init_opencode_probe=__esm({"server/drivers/acp/opencode-probe.ts"(){"use strict";init_atomic();init_config3();init_contracts();init_procs();init_config_options();init_session_delete();DISCOVERY_TIMEOUT_MS2=2e4,EFFORT_SURVEY_MS=8e3;discoveryFolder=null;probeLedgerPath=cwd=>join89(cwd,".openmaus-probe-sessions.json")}});import{existsSync as existsSync35,mkdirSync as mkdirSync37,readFileSync as readFileSync49,statSync as statSync22,writeFileSync as writeFileSync22}from"node:fs";import{homedir as homedir25}from"node:os";import{dirname as dirname35,isAbsolute as isAbsolute19,join as join90,relative as relative9,resolve as resolvePath,sep as sep3}from"node:path";function localModelRecord(record12){let api2=record12.api&&typeof record12.api=="object"&&!Array.isArray(record12.api)?record12.api:{};if(typeof api2.url!=
|
|
7685
7689
|
"string")return!1;try{let host2=new URL(api2.url).hostname.replace(/^\[|\]$/gu,"");return host2==="localhost"||host2==="127.0.0.1"||host2==="::1"}catch{return!1}}function isFreeOpenCodeModel(id){return freeModels.has(id)?!0:paidModels.has(id)?!1:/(?:^|[-_/])free$/iu.test(id)}function preferredOpenCodeModel(offered,current){if(current&&offered.includes(current)&&isFreeOpenCodeModel(current))return current;let free=offered.filter(isFreeOpenCodeModel);return free.find(id=>id.startsWith("opencode/"))??
|
|
7686
7690
|
free[0]??(current&&offered.includes(current)?current:offered[0]??"")}function parseOpenCodeModels(stdout2){let options2=[],free=[],paid=[],seen=new Set,slug2=null,jsonLines=[],flush=()=>{if(!slug2||seen.has(slug2))return;let separator=slug2.indexOf("/"),provider=slug2.slice(0,separator),model=slug2.slice(separator+1),record12={},raw=jsonLines.join(`
|
|
7687
7691
|
`).trim();if(raw)try{let parsed=JSON.parse(raw);parsed&&typeof parsed=="object"&&!Array.isArray(parsed)&&(record12=parsed)}catch{}if(record12.status==="deprecated")return;let cost2=record12.cost&&typeof record12.cost=="object"&&!Array.isArray(record12.cost)?record12.cost:null;cost2&&typeof cost2.input=="number"&&typeof cost2.output=="number"&&(cost2.input===0&&cost2.output===0?free:paid).push(slug2);let name=typeof record12.name=="string"&&record12.name.trim()?record12.name.trim():labelForModel(
|
|
@@ -7694,21 +7698,21 @@ settleMs,allowEnv),readMetadata=()=>runOpenCodeModelsVerbose(cli,listing,allowEn
|
|
|
7694
7698
|
status==="fulfilled"?session.value:null,live=probe?catalogFromOpenCodeSession(probe.session):null,catalog=null;if(probe&&live){let details=new Map((metadata?.options??[]).map(option=>[option.id,option])),options3=live.options.map(option=>withEfforts({...option,...details.get(option.id),id:option.id},probe.efforts.get(option.id)));catalog={default:preferredOpenCodeModel(options3.map(option=>option.id),live.current),options:options3}}else metadata?.options.length&&(catalog={default:preferredOpenCodeModel(
|
|
7695
7699
|
metadata.options.map(option=>option.id)),options:metadata.options});return catalog?(options2.refresh&&!sameModelIds(lastSuccessfulCatalog.get(cli),catalog)&&catalogRevisions.set(cli,(catalogRevisions.get(cli)??0)+1),lastSuccessfulCatalog.set(cli,catalog),catalog):lastSuccessfulCatalog.get(cli)??NO_MODELS}function openCodeSpawnFingerprint(env,cli){return`${openCodeLoginsFingerprint(env)}#${catalogRevisions.get(cli)??0}`}async function canRunOpenCode(environment,cli,discover=discoverOpenCodeModels,allowEnv=[]){
|
|
7696
7700
|
if(lastSuccessfulCatalog.get(cli)?.options.length)return!0;let cached4=discoveryProbeCache.get(cli);if(cached4&&cached4.expiresAt>Date.now())return cached4.result;let entry={expiresAt:Number.POSITIVE_INFINITY,result:Promise.resolve(!1)};return entry.result=discover(environment,cli,{allowEnv}).then(catalog=>catalog.options.length>0,()=>!1).finally(()=>{entry.expiresAt=Date.now()+DISCOVERY_PROBE_TTL_MS}),discoveryProbeCache.set(cli,entry),entry.result}function openCodeProviderKeysAllowed(state){return!state.
|
|
7697
|
-
cloudHome&&!state.hostedWorkspace&&!state.organisationManaged&&!state.sharedSignIn}function withholdProviderKeysWhenManaged(env,_config,_instanceId,instanceEnvironment){if(!providerKeysAllowed())for(let key2 of OPENCODE_PROVIDER_ENV)Object.hasOwn(instanceEnvironment,key2)||delete env[key2]}function opencodeConfigDir(env){let home2=env.HOME||env.USERPROFILE||
|
|
7698
|
-
let inject=decodeInjectId(modelId2);if(!inject)return modelId2;let host2=localHost(inject.host);if(!host2)return modelId2;let native=`${inject.host}/${inject.model}`,dir=opencodeConfigDir(env);
|
|
7701
|
+
cloudHome&&!state.hostedWorkspace&&!state.organisationManaged&&!state.sharedSignIn}function withholdProviderKeysWhenManaged(env,_config,_instanceId,instanceEnvironment){if(!providerKeysAllowed())for(let key2 of OPENCODE_PROVIDER_ENV)Object.hasOwn(instanceEnvironment,key2)||delete env[key2]}function opencodeConfigDir(env){let home2=env.HOME||env.USERPROFILE||homedir25();return join90(env.XDG_CONFIG_HOME||join90(home2,".config"),"opencode")}function ensureOpenCodeInjectModel(modelId2,env=process.env){
|
|
7702
|
+
let inject=decodeInjectId(modelId2);if(!inject)return modelId2;let host2=localHost(inject.host);if(!host2)return modelId2;let native=`${inject.host}/${inject.model}`,dir=opencodeConfigDir(env);mkdirSync37(dir,{recursive:!0});let path3=join90(dir,"opencode.json"),config3={$schema:"https://opencode.ai/config.json"};if(existsSync35(path3))try{config3=JSON.parse(readFileSync49(path3,"utf8"))}catch{}let providers=config3.provider&&typeof config3.provider=="object"&&!Array.isArray(config3.provider)?{...config3.
|
|
7699
7703
|
provider}:{},previous2=providers[inject.host],existing=previous2&&typeof previous2=="object"&&!Array.isArray(previous2)?{...previous2}:{npm:"@ai-sdk/openai-compatible",name:host2.label,options:{},models:{}},options2=existing.options&&typeof existing.options=="object"&&!Array.isArray(existing.options)?{...existing.options}:{};options2.baseURL=host2.baseUrl,options2.apiKey||(options2.apiKey=hostApiKey(host2,env));let models2=existing.models&&typeof existing.models=="object"&&!Array.isArray(existing.
|
|
7700
|
-
models)?{...existing.models}:{};return models2[inject.model]||(models2[inject.model]={name:`${inject.model} (${host2.label})`}),providers[inject.host]={...existing,npm:existing.npm||"@ai-sdk/openai-compatible",name:existing.name||host2.label,options:options2,models:models2},config3.provider=providers,
|
|
7701
|
-
`),native}function openCodeLogPath(env){return
|
|
7702
|
-
map(root=>
|
|
7704
|
+
models)?{...existing.models}:{};return models2[inject.model]||(models2[inject.model]={name:`${inject.model} (${host2.label})`}),providers[inject.host]={...existing,npm:existing.npm||"@ai-sdk/openai-compatible",name:existing.name||host2.label,options:options2,models:models2},config3.provider=providers,writeFileSync22(path3,`${JSON.stringify(config3,null,2)}
|
|
7705
|
+
`),native}function openCodeLogPath(env){return join90(env.XDG_DATA_HOME||join90(env.HOME||env.USERPROFILE||homedir25(),".local","share"),"opencode","log","opencode.log")}function storedAuthPaths(env){let home2=env.HOME||env.USERPROFILE||homedir25(),roots=[env.XDG_DATA_HOME||join90(home2,".local","share"),process.platform==="darwin"?join90(home2,"Library","Application Support"):process.platform==="win32"?env.LOCALAPPDATA||join90(home2,"AppData","Local"):""].filter(Boolean);return[...new Set(roots)].
|
|
7706
|
+
map(root=>join90(root,"opencode","auth.json"))}function usableAuthEntry(parsed){return Object.values(parsed).some(auth=>{if(!auth||typeof auth!="object"||Array.isArray(auth))return!1;let entry=auth;return!!(entry.key||entry.access||entry.refresh)})}function hasStoredOpenCodeAuth(env){let candidates=[];env.OPENCODE_AUTH_CONTENT&&candidates.push(env.OPENCODE_AUTH_CONTENT);for(let path3 of storedAuthPaths(env))try{candidates.push(readFileSync49(path3,"utf8"))}catch{}return candidates.some(raw=>{try{
|
|
7703
7707
|
return usableAuthEntry(JSON.parse(raw))}catch{return!1}})}function ownOpenCodeAccess(env){return!!env.OPENCODE_API_KEY||hasStoredOpenCodeAuth(env)||OPENCODE_PROVIDER_ENV.some(key2=>!!env[key2]?.trim())}function openCodeFreeFallback(ownAccess,models2){return!ownAccess&&models2.options.length>0&&models2.options.every(option=>option.custom===!0||OPENCODE_OWN_MODEL.test(option.id))}function withinFolder(path3,folder){let rest=relative9(resolvePath(folder),resolvePath(path3));return rest===""||rest!==
|
|
7704
|
-
".."&&!rest.startsWith(`..${sep3}`)&&!isAbsolute19(rest)}function openMausOwnsWorkingFolder(cwd){return[
|
|
7708
|
+
".."&&!rest.startsWith(`..${sep3}`)&&!isAbsolute19(rest)}function openMausOwnsWorkingFolder(cwd){return[join90(DATA_DIR,"workspaces"),join90(DATA_DIR,"task-workspaces")].some(root=>withinFolder(cwd,root)&&resolvePath(cwd)!==resolvePath(root))}function openCodeOwnedDirectories(botId,cwd){let directories=[ATTACHMENTS_DIR];return botId&&/^[\w-][\w.-]*$/u.test(botId)&&botId!==".."&&directories.push(join90(DATA_DIR,"workspaces",botId)),cwd?directories.filter(directory=>!withinFolder(cwd,directory)):directories}
|
|
7705
7709
|
function parseJsonc(text13){let plain="",inString=!1;for(let index2=0;index2<text13.length;index2+=1){let character=text13[index2];if(inString)plain+=character,character==="\\"?plain+=text13[++index2]??"":character==='"'&&(inString=!1);else if(character==='"')inString=!0,plain+=character;else if(character==="/"&&text13[index2+1]==="/"){for(;index2<text13.length&&text13[index2]!==`
|
|
7706
7710
|
`;)index2+=1;plain+=`
|
|
7707
|
-
`}else if(character==="/"&&text13[index2+1]==="*"){for(index2+=2;index2<text13.length&&!(text13[index2]==="*"&&text13[index2+1]==="/");)index2+=1;index2+=1}else plain+=character}try{return JSON.parse(plain.replace(/,(\s*[}\]])/gu,"$1"))}catch{return}}function readText2(path3){try{return
|
|
7708
|
-
t"?config3.permission:void 0;if(!permission||typeof permission!="object"||Array.isArray(permission))return;let value=permission.external_directory;typeof value=="string"?rule=value:value&&typeof value=="object"&&!Array.isArray(value)&&(rule=rule&&typeof rule=="object"?{...rule,...value}:value)},global=opencodeConfigDir(env);for(let name of["config.json","opencode.json","opencode.jsonc"])apply(readText2(
|
|
7709
|
-
if(projectConfig){for(let folder=resolvePath(cwd);projectFolders.push(folder),!(
|
|
7710
|
-
[]];for(let folder of configFolders)for(let name of["opencode.json","opencode.jsonc"])apply(readText2(
|
|
7711
|
-
length)return;let existing=permission.external_directory,rules;if(typeof existing=="string")rules={"*":existing};else if(existing&&typeof existing=="object"&&!Array.isArray(existing))rules={...existing};else{let configured=configuredOpenCodeFolderAction(env,cwd,env.OPENCODE_DISABLE_PROJECT_CONFIG!=="1");rules=configured?{"*":configured}:{}}for(let directory of directories)rules[directory]="allow",rules[
|
|
7711
|
+
`}else if(character==="/"&&text13[index2+1]==="*"){for(index2+=2;index2<text13.length&&!(text13[index2]==="*"&&text13[index2+1]==="/");)index2+=1;index2+=1}else plain+=character}try{return JSON.parse(plain.replace(/,(\s*[}\]])/gu,"$1"))}catch{return}}function readText2(path3){try{return readFileSync49(path3,"utf8")}catch{return}}function configuredOpenCodeFolderAction(env,cwd,projectConfig){let rule,apply=raw=>{if(!raw)return;let config3=parseJsonc(raw),permission=config3&&typeof config3=="objec\
|
|
7712
|
+
t"?config3.permission:void 0;if(!permission||typeof permission!="object"||Array.isArray(permission))return;let value=permission.external_directory;typeof value=="string"?rule=value:value&&typeof value=="object"&&!Array.isArray(value)&&(rule=rule&&typeof rule=="object"?{...rule,...value}:value)},global=opencodeConfigDir(env);for(let name of["config.json","opencode.json","opencode.jsonc"])apply(readText2(join90(global,name)));env.OPENCODE_CONFIG&&apply(readText2(env.OPENCODE_CONFIG));let projectFolders=[];
|
|
7713
|
+
if(projectConfig){for(let folder=resolvePath(cwd);projectFolders.push(folder),!(existsSync35(join90(folder,".git"))||dirname35(folder)===folder);folder=dirname35(folder));for(let folder of[...projectFolders].reverse())for(let name of["opencode.json","opencode.jsonc"])apply(readText2(join90(folder,name)))}let home2=env.HOME||env.USERPROFILE||homedir25(),configFolders=[...projectFolders.map(folder=>join90(folder,".opencode")),join90(home2,".opencode"),...env.OPENCODE_CONFIG_DIR?[env.OPENCODE_CONFIG_DIR]:
|
|
7714
|
+
[]];for(let folder of configFolders)for(let name of["opencode.json","opencode.jsonc"])apply(readText2(join90(folder,name)));return apply(env.OPENCODE_CONFIG_CONTENT),typeof rule=="string"?rule:void 0}function allowOwnedDirectories(env,botId,cwd){let permission={};if(env.OPENCODE_PERMISSION)try{let parsed=JSON.parse(env.OPENCODE_PERMISSION);if(!parsed||typeof parsed!="object"||Array.isArray(parsed))return;permission=parsed}catch{return}let directories=openCodeOwnedDirectories(botId,cwd);if(!directories.
|
|
7715
|
+
length)return;let existing=permission.external_directory,rules;if(typeof existing=="string")rules={"*":existing};else if(existing&&typeof existing=="object"&&!Array.isArray(existing))rules={...existing};else{let configured=configuredOpenCodeFolderAction(env,cwd,env.OPENCODE_DISABLE_PROJECT_CONFIG!=="1");rules=configured?{"*":configured}:{}}for(let directory of directories)rules[directory]="allow",rules[join90(directory,"*")]="allow";permission.external_directory=rules,env.OPENCODE_PERMISSION=JSON.
|
|
7712
7716
|
stringify(permission)}function describeOpenCodeAccountError(code,model,where={cloudHome:cloudHomeConfigured()}){let provider=model&&model.includes("/")?model.slice(0,model.indexOf("/")):"",zen=provider==="opencode",go2=provider==="opencode-go",label2=providerLabel(provider),name=zen?"OpenCode Zen":go2?"OpenCode Go":provider?label2.length>24?provider.slice(0,24):label2:"OpenCode";switch(code){case"invalid_credentials":return zen||go2||!provider?"OpenCode rejected its key, or has none for this mod\
|
|
7713
7717
|
el. Add or replace the OpenCode key in Settings \u2192 API keys.":where.cloudHome?`OpenCode's ${name} key for this model is missing or was rejected. Save it under Keys for other OpenCode providers in Settings \u2192 API keys.`:`OpenCode's ${name} key for this model is missing or was rejected. Fix it with \`opencode auth login\`, or choose another model.`;case"insufficient_funds":return zen||!provider?"Your OpenCode Zen balance has run out. Add credit at opencode.ai, or choose one of Zen's free m\
|
|
7714
7718
|
odels for this bot.":`Your ${name} account has run out of credit. Add credit there, or choose another model for this bot.`;case"inactive_subscription":return go2||!provider?"This model needs an active OpenCode Go subscription. Subscribe at opencode.ai, or choose a Zen model for this bot.":`This model needs an active ${name} subscription. Renew it there, or choose another model for this bot.`;case"quota_or_region_restriction":return`${name} says this account's usage limit has been reached. Wait f\
|
|
@@ -7726,26 +7730,26 @@ op"].map(permission=>[permission,"allow"])))},pickAuthMethod:()=>null,authFailur
|
|
|
7726
7730
|
markOpenCodeCatalogRefreshed(instanceId,(sources.now??Date.now)()),await refreshLiveModelLists(environment,{lists:sources.liveLists,fetch:sources.fetch,now:sources.now}),declareLiveOpenCodeModels(environment,sources.liveLists),mergeLocalInject(await loadCatalog(environment,config3.cli,{refresh:fresh===!0,allowEnv}),environment)),buildPromptText:turn=>turn.system?`${turn.system}
|
|
7727
7731
|
|
|
7728
7732
|
${turn.text}`:turn.text}),ACCOUNT_ERROR_TEXT=[[/insufficient (?:account )?(?:funds|balance|credits?)|out of credits?|no credits? (?:left|remaining)|payment required|\b402\b/iu,"insufficient_funds"],[/\bquota\b|usage limit|\b(?:Free|Go)UsageLimitError\b|(?:hourly|daily|weekly|monthly|5-hour) limit/iu,"quota_or_region_restriction"],[/\bsubscription\b/iu,"inactive_subscription"],[/invalid api key|api key (?:is )?(?:invalid|missing|revoked|expired)|incorrect api key|unauthori[sz]ed|\b401\b|authentication (?:failed|required)|(?:^|internal error: )user not found\b/iu,
|
|
7729
|
-
"invalid_credentials"]],FREE_MODEL_LIMIT=/\bfree(?:UsageLimitError|\s+usage\s+limit)\b/iu;OpenCodeDriver=createOpenCodeDriver()}});import{chmodSync as chmodSync9,existsSync as
|
|
7733
|
+
"invalid_credentials"]],FREE_MODEL_LIMIT=/\bfree(?:UsageLimitError|\s+usage\s+limit)\b/iu;OpenCodeDriver=createOpenCodeDriver()}});import{chmodSync as chmodSync9,existsSync as existsSync36,mkdirSync as mkdirSync38,readFileSync as readFileSync50,writeFileSync as writeFileSync23}from"node:fs";import{createHash as createHash27}from"node:crypto";import{join as join91}from"node:path";function isRecord9(value){return!!value&&typeof value=="object"&&!Array.isArray(value)}function readQwenRoutes(env){let settings2;try{settings2=JSON.parse(readFileSync50(join91(harnessHome("qwen",env),"settings.json"),"utf8"))}catch{return[]}if(!isRecord9(
|
|
7730
7734
|
settings2)||!isRecord9(settings2.modelProviders))return[];let routes=[],seen=new Set,mappings=isRecord9(settings2.providerProtocol)?settings2.providerProtocol:{};for(let[provider,rows]of Object.entries(settings2.modelProviders)){let protocol=Object.hasOwn(mappings,provider)?mappings[provider]:provider;if(!(typeof protocol!="string"||!PROTOCOLS.has(protocol)||!Array.isArray(rows)))for(let row of rows){if(!isRecord9(row)||typeof row.id!="string")continue;let model=row.id;if(!model.trim()||row.baseUrl!==
|
|
7731
7735
|
void 0&&typeof row.baseUrl!="string")continue;let baseUrl=typeof row.baseUrl=="string"&&row.baseUrl?row.baseUrl:void 0;if(baseUrl)try{new URL(baseUrl)}catch{throw new Error("A Qwen model has an invalid endpoint. Fix its baseUrl in Qwen settings and refresh models.")}let identity=JSON.stringify([protocol,model,baseUrl??null]);seen.has(identity)||(seen.add(identity),!(row.imageOnly===!0||row.voiceOnly===!0||row.fastOnly===!0)&&routes.push({id:`${model}(${protocol})`,model,provider,protocol,baseUrl,
|
|
7732
7736
|
label:typeof row.name=="string"&&row.name?row.name:model,envKey:typeof row.envKey=="string"?row.envKey:void 0}))}}let counts=new Map;for(let route of routes)counts.set(route.id,(counts.get(route.id)??0)+1);for(let route of routes){if(counts.get(route.id)===1)continue;let endpoint=route.baseUrl??(route.protocol==="openai"?"https://api.openai.com/v1":""),publicEndpoint=null;if(endpoint)try{let url3=new URL(endpoint);url3.username="",url3.password="",url3.search="",url3.hash="",publicEndpoint=url3.
|
|
7733
7737
|
href}catch{throw new Error("A Qwen model has an invalid endpoint. Fix its baseUrl in Qwen settings and refresh models.")}let identity=[route.id,route.label,route.envKey??null,route.baseUrl===void 0,publicEndpoint];route.id=`qwen-route:v1:${createHash27("sha256").update(JSON.stringify(identity)).digest("base64url").slice(0,16)}`}if(new Set(routes.map(route=>route.id)).size!==routes.length)throw new Error("Qwen has indistinguishable model routes. Give them distinct names, envKey values, or public \
|
|
7734
7738
|
endpoints in Qwen settings.");return routes}function readQwenModelCatalog(env=process.env){let options2=readQwenRoutes(env).map(({id,model,label:label2,provider})=>({id,label:qualifiedModelLabel(model,label2,{redundantWhen:(id2,name)=>name.toLocaleLowerCase().endsWith(id2.toLocaleLowerCase())}),custom:!0,provider}));return{default:options2[0]?.id??"",options:options2}}function envKeyFor(hostId){return`OPENMAUSBOT_QWEN_${hostId.toUpperCase().replace(/[^A-Z0-9]+/g,"_")}_API_KEY`}function ensureQwenInjectModel(modelId2,env=process.
|
|
7735
|
-
env){let inject=decodeInjectId(modelId2);if(!inject)return modelId2;let host2=localHost(inject.host);if(!host2)return modelId2;let dir=harnessHome("qwen",env);
|
|
7739
|
+
env){let inject=decodeInjectId(modelId2);if(!inject)return modelId2;let host2=localHost(inject.host);if(!host2)return modelId2;let dir=harnessHome("qwen",env);mkdirSync38(dir,{recursive:!0});let path3=join91(dir,"settings.json"),settings2={};if(existsSync36(path3))try{settings2=JSON.parse(readFileSync50(path3,"utf8"))}catch{}let keyName2=envKeyFor(inject.host),key2=hostApiKey(host2,env),envMap=settings2.env&&typeof settings2.env=="object"&&!Array.isArray(settings2.env)?{...settings2.env}:{};envMap[keyName2]=
|
|
7736
7740
|
key2,settings2.env=envMap;let providers=settings2.modelProviders&&typeof settings2.modelProviders=="object"&&!Array.isArray(settings2.modelProviders)?{...settings2.modelProviders}:{},openai=Array.isArray(providers.openai)?[...providers.openai]:[];openai.find(row=>row&&typeof row=="object"&&row.id===inject.model&&row.baseUrl===host2.baseUrl)||(openai.push({id:inject.model,name:`${inject.model} (${host2.label})`,baseUrl:host2.baseUrl,envKey:keyName2}),providers.openai=openai,settings2.modelProviders=
|
|
7737
|
-
providers),
|
|
7741
|
+
providers),writeFileSync23(path3,`${JSON.stringify(settings2,null,2)}
|
|
7738
7742
|
`,{mode:384});try{chmodSync9(path3,384)}catch{}return inject.model}async function resolveModels2(env){let catalog=await mergeLocalInject(readQwenModelCatalog(env),env),routes=readQwenRoutes(env),replacements=new Map;for(let option of catalog.options){let injected=decodeInjectId(option.id);if(!injected)continue;let endpoint=localHost(injected.host)?.baseUrl;for(let route of routes)route.protocol==="openai"&&route.model===injected.model&&route.baseUrl===endpoint&&replacements.set(route.id,option.id)}
|
|
7739
7743
|
let options2=catalog.options.filter(option=>!replacements.has(option.id)),preferred=replacements.get(catalog.default)??catalog.default;return{default:options2.some(option=>option.id===preferred)?preferred:options2[0]?.id??"",options:options2}}function resolveQwenTurnModel(model,env){if(!model)return model;let injected=decodeInjectId(model);injected&&ensureQwenInjectModel(model,env);let routes=readQwenRoutes(env);if(injected){let route=routes.find(row=>row.protocol==="openai"&&row.model===injected.
|
|
7740
7744
|
model&&row.baseUrl===localHost(injected.host)?.baseUrl);if(!route)throw new Error("Qwen could not configure this local model. Refresh models and select it again.");return route.id}if(routes.some(route=>route.id===model))return model;let matches2=routes.filter(route=>route.model===model);if(matches2.length>1)throw new Error("This Qwen model has multiple providers. Refresh models and select the intended provider again.");if(!matches2.length)throw new Error("This Qwen model is no longer configured.\
|
|
7741
|
-
Refresh models and select it again.");return matches2[0].id}function qwenDebugLogPath(env,sessionId){if(["","0","false","off","no"].includes((env.QWEN_DEBUG_LOG_FILE??"").trim().toLowerCase())||!/^[\w-]{1,128}$/.test(sessionId))return null;let base2=env.QWEN_RUNTIME_DIR||env.QWEN_HOME||harnessHome("qwen",env);return
|
|
7745
|
+
Refresh models and select it again.");return matches2[0].id}function qwenDebugLogPath(env,sessionId){if(["","0","false","off","no"].includes((env.QWEN_DEBUG_LOG_FILE??"").trim().toLowerCase())||!/^[\w-]{1,128}$/.test(sessionId))return null;let base2=env.QWEN_RUNTIME_DIR||env.QWEN_HOME||harnessHome("qwen",env);return join91(base2,"debug",`${sessionId}.txt`)}function qwenApprovalArgs(fullAuto,approvalMode){return fullAuto?["--yolo"]:approvalMode==="auto"?["--approval-mode","auto"]:approvalMode===
|
|
7742
7746
|
"edits"?["--approval-mode","auto-edit"]:[]}var EMPTY,PROTOCOLS,support8,QwenAgentDriver,init_qwen=__esm({"server/drivers/acp/qwen.ts"(){"use strict";init_contracts();init_env_path();init_quiet_status();init_local_inject();init_core3();EMPTY={default:"",options:[]};PROTOCOLS=new Set(["openai","anthropic","gemini","vertex-ai"]);support8={driverKind:"qwenAgent",displayName:"Qwen",access:"custom",models:EMPTY,resolveModels:resolveModels2,resolveTurnModel:resolveQwenTurnModel,defaultCli:"qwen",nativeSource:"\
|
|
7743
7747
|
qwen.acp",loginNote:"Qwen Code CLI is not installed",install:{command:{darwin:"curl -fsSL https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen-standalone.sh | bash",linux:"curl -fsSL https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen-standalone.sh | bash",win32:"irm https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen-standalone.ps1 | iex"},docsUrl:"https://qwenlm.github.io/qwen-code-docs/en/users/overview/"},spawnArgs:(config3,turn)=>[
|
|
7744
7748
|
"--acp",...qwenApprovalArgs(config3.fullAuto,turn.approvalMode)],restartOnMcpChange:!0,selectModel:{configId:"model"},pickAuthMethod:()=>null,authFailure:"continue",isAuthenticated:()=>!0,buildPromptText:turn=>turn.system?`${turn.system}
|
|
7745
7749
|
|
|
7746
7750
|
${turn.text}`:turn.text,transformEnv:env=>{env.QWEN_DEBUG_LOG_FILE===void 0&&(env.QWEN_DEBUG_LOG_FILE="1")},statusLog:{path:qwenDebugLogPath,parse:parseQwenLogLine}},QwenAgentDriver=createAcpDriver(support8)}});var CONFIGURE_HINT,support9,base,CustomAcpDriver,init_custom=__esm({"server/drivers/acp/custom.ts"(){"use strict";init_core3();init_custom_model_catalog();CONFIGURE_HINT='a custom ACP engine needs its command \u2014 add "config": { "cli": "<your-agent> acp" } to this instance in config.json, or use Settings \u2192 Engines \u2192 Set CLI\u2026',support9={driverKind:"customAcp",displayName:"Custom (ACP)",access:"custom",models:{default:"agent-default",options:[{id:"agent-default",label:"Agent defa\
|
|
7747
7751
|
ult",custom:!0}]},defaultCli:"",nativeSource:"custom.acp",loginNote:CONFIGURE_HINT,spawnArgs:()=>[],resolveModels:resolveCustomAcpModels,resolveModelsOnCreate:!1,selectModel:{configId:"model",agentDefault:"agent-default",allowLegacy:!0},modelVariants:!0,pickAuthMethod:()=>null,authFailure:"continue",isAuthenticated:()=>!0},base=createAcpDriver(support9),CustomAcpDriver={...base,decodeConfig(raw){let decoded2=base.decodeConfig(raw);if(!decoded2.cli.trim())throw new Error(CONFIGURE_HINT);return decoded2},
|
|
7748
|
-
async create(input2){if(!input2.config.cli.trim())throw new Error(CONFIGURE_HINT);let name=input2.displayName?.trim();return(name?createAcpDriver({...support9,displayName:name}):base).create(input2)}}}});import{accessSync,constants as constants5,existsSync as
|
|
7752
|
+
async create(input2){if(!input2.config.cli.trim())throw new Error(CONFIGURE_HINT);let name=input2.displayName?.trim();return(name?createAcpDriver({...support9,displayName:name}):base).create(input2)}}}});import{accessSync,constants as constants5,existsSync as existsSync37,mkdirSync as mkdirSync39,readFileSync as readFileSync51,statSync as statSync23,writeFileSync as writeFileSync24}from"node:fs";import{homedir as homedir26}from"node:os";import{join as join92}from"node:path";function bindHermesScreenshotCompat(env,modelId2){delete env[HERMES_OPENMAUS_SCREENSHOT_COMPAT],delete env[HERMES_OPENMAUS_SCREENSHOT_COMPAT_MODEL];let inject=decodeInjectId(modelId2);inject&&(env[HERMES_OPENMAUS_SCREENSHOT_COMPAT]=
|
|
7749
7753
|
"1",env[HERMES_OPENMAUS_SCREENSHOT_COMPAT_MODEL]=inject.model)}function quoteYaml(value){return/^[\w./:+-]+$/.test(value)?value:JSON.stringify(value)}function upsertHermesProvider(text13,hostId,baseUrl,apiKey){let block2=[` ${hostId}:`,` base_url: ${quoteYaml(baseUrl)}`,` api_key: ${quoteYaml(apiKey)}`,""].join(`
|
|
7750
7754
|
`);if(/^providers:\s*$/m.test(text13)){let replaced=replaceHermesHostBlock(text13,hostId,block2);return replaced!==null?replaced:text13.replace(/^providers:\s*$/m,`providers:
|
|
7751
7755
|
${block2.trimEnd()}`)}return`${text13&&!text13.endsWith(`
|
|
@@ -7755,20 +7759,20 @@ providers:
|
|
|
7755
7759
|
${block2}`}function replaceHermesHostBlock(text13,hostId,block2){let lines2=text13.split(`
|
|
7756
7760
|
`),start=lines2.findIndex(line3=>line3===` ${hostId}:`);if(start<0)return null;let end=start+1;for(;end<lines2.length;){let line3=lines2[end];if(/^ \S/.test(line3)||/^\S/.test(line3))break;end++}for(;end>start+1&&lines2[end-1]==="";)end--;return[...lines2.slice(0,start),...block2.replace(/\n$/,"").split(`
|
|
7757
7761
|
`),...lines2.slice(end)].join(`
|
|
7758
|
-
`)}function ensureHermesInjectProvider(modelId2,env=process.env){let inject=decodeInjectId(modelId2);if(!inject)return modelId2;let host2=localHost(inject.host);if(!host2)return modelId2;let dir=env.HERMES_HOME||harnessHome("hermes",env);
|
|
7762
|
+
`)}function ensureHermesInjectProvider(modelId2,env=process.env){let inject=decodeInjectId(modelId2);if(!inject)return modelId2;let host2=localHost(inject.host);if(!host2)return modelId2;let dir=env.HERMES_HOME||harnessHome("hermes",env);mkdirSync39(dir,{recursive:!0});let path3=join92(dir,"config.yaml"),text13="";try{text13=readFileSync51(path3,"utf8")}catch{text13=""}let next=upsertHermesProvider(text13,inject.host,host2.baseUrl,hostApiKey(host2,env));return next!==text13&&writeFileSync24(path3,
|
|
7759
7763
|
next),hermesAcpModelId(modelId2)??modelId2}function hermesAcpModelId(modelId2){let inject=decodeInjectId(modelId2);if(inject)return`custom:${inject.host}:${inject.model}`;let native=typeof modelId2=="string"?modelId2.trim():"";return native&&!native.includes(INJECT_SEP)&&/^[a-z0-9_-]+:[\w./:-]+$/i.test(native)?native:null}function hermesConfigOption(model){return{id:HERMES_CONFIG_MODEL_ID,label:model?`${model} (Hermes config)`:"Hermes default (config)",custom:!0}}function nonEmptyDotenvValue(text13,name){
|
|
7760
7764
|
let match=new RegExp(`^[ \\t]*(?:export[ \\t]+)?${name}[ \\t]*=[ \\t]*([^\\r\\n]*)$`,"m").exec(text13);if(!match)return null;let raw=match[1].trim();if(!raw||raw.startsWith("#"))return null;let quote=raw[0];if(quote==='"'||quote==="'"){let closing=raw.indexOf(quote,1);if(closing<0)return null;let trailing=raw.slice(closing+1).trim();return trailing&&!trailing.startsWith("#")?null:raw.slice(1,closing).trim()||null}return raw.replace(/[ \t]+#.*$/,"").trim()||null}function yamlString(value){return typeof value==
|
|
7761
7765
|
"string"?value.trim():""}function hermesConfigDefault(text13){let raw;try{raw=parse4(text13)}catch{return null}if(!raw||typeof raw!="object"||Array.isArray(raw))return null;let config3=raw,rootProvider=yamlString(config3.provider);if(typeof config3.model=="string"){let model=config3.model.trim();return model?{model,provider:rootProvider}:null}if(!config3.model||typeof config3.model!="object"||Array.isArray(config3.model))return null;let modelConfig=config3.model,outerProvider=yamlString(modelConfig.
|
|
7762
7766
|
provider)||rootProvider;for(let key2 of["default","model","name"]){let candidate=modelConfig[key2],scalar=yamlString(candidate);if(scalar)return{model:scalar,provider:outerProvider};if(!candidate||typeof candidate!="object"||Array.isArray(candidate))continue;let nested=candidate,nestedModel=yamlString(nested.model)||yamlString(nested.default);if(!nestedModel)continue;let nestedProvider=yamlString(nested.provider);return{model:nestedModel,provider:(!outerProvider||outerProvider==="auto")&&nestedProvider||
|
|
7763
|
-
outerProvider}}return null}function hermesConfiguredModel(env=process.env){let dir=env.HERMES_HOME||harnessHome("hermes",env),secrets="";try{secrets=
|
|
7764
|
-
has(configuredProvider)||configuredProvider.startsWith("custom:");return configuredDefault&&configIsLocal||!hasHostedProviderKey&&!(configuredDefault!==null)?null:hermesConfigOption(configuredDefault?.model??"")}function hermesInstalled(cli){let trimmed=cli.trim(),head=trimmed.includes(" ")&&
|
|
7765
|
-
try{return statSync23(found).isFile()?(accessSync(found,constants5.X_OK),!0):!1}catch{return!1}})}function yamlMap(value){return value&&typeof value=="object"&&!Array.isArray(value)?value:{}}function hermesUsesProbedProvider(env){let dir=env.HERMES_HOME||harnessHome("hermes",env);try{let text13=
|
|
7767
|
+
outerProvider}}return null}function hermesConfiguredModel(env=process.env){let dir=env.HERMES_HOME||harnessHome("hermes",env),secrets="";try{secrets=readFileSync51(join92(dir,".env"),"utf8")}catch{}let hasHostedProviderKey=HERMES_HOSTED_PROVIDER_KEYS.some(name=>nonEmptyDotenvValue(secrets,name)),configuredDefault=null;try{configuredDefault=hermesConfigDefault(readFileSync51(join92(dir,"config.yaml"),"utf8"))}catch{}let configuredProvider=configuredDefault?.provider.toLowerCase()??"",configIsLocal=HERMES_LOCAL_CONFIG_PROVIDERS.
|
|
7768
|
+
has(configuredProvider)||configuredProvider.startsWith("custom:");return configuredDefault&&configIsLocal||!hasHostedProviderKey&&!(configuredDefault!==null)?null:hermesConfigOption(configuredDefault?.model??"")}function hermesInstalled(cli){let trimmed=cli.trim(),head=trimmed.includes(" ")&&existsSync37(trimmed)?trimmed:splitCliString(trimmed)[0]??"";return process.platform==="win32"?whichWin(head)!==null&&!/\.(cmd|bat)$/i.test(resolveCliSpawn(trimmed,[]).command):findCliCandidates(head).some(found=>{
|
|
7769
|
+
try{return statSync23(found).isFile()?(accessSync(found,constants5.X_OK),!0):!1}catch{return!1}})}function yamlMap(value){return value&&typeof value=="object"&&!Array.isArray(value)?value:{}}function hermesUsesProbedProvider(env){let dir=env.HERMES_HOME||harnessHome("hermes",env);try{let text13=readFileSync51(join92(dir,"config.yaml"),"utf8"),provider=hermesConfigDefault(text13)?.provider.toLowerCase()??"",probe=HERMES_PROBED_PROVIDERS.has(provider)?localHost(provider):void 0;if(!probe)return!1;
|
|
7766
7770
|
let config3=yamlMap(parse4(text13)),baseUrl=yamlString(yamlMap(config3.model).base_url)||yamlString(yamlMap(yamlMap(config3.providers)[provider]).base_url)||yamlString(config3.base_url);if(!baseUrl)return!0;let configured=new URL(baseUrl),probed2=new URL(probe.baseUrl);return PROBED_LOOPBACK_HOSTS.has(configured.hostname)&&configured.protocol===probed2.protocol&&configured.port===probed2.port}catch{return!1}}function hermesAcpModelsTimeoutMs(env){let raw=env[HERMES_ACP_MODELS_TIMEOUT_ENV];if(raw===
|
|
7767
7771
|
void 0)return HERMES_ACP_MODELS_DEFAULT_TIMEOUT_MS;let parsed=Number(raw);return Number.isInteger(parsed)&&parsed>0&&parsed<=2147483647?parsed:HERMES_ACP_MODELS_DEFAULT_TIMEOUT_MS}async function fetchHermesAcpModels(cli,env,allowEnv=[]){return await new Promise(resolve35=>{let child;try{let resolved2=resolveCli(cli,["acp"],env);child=spawnCli(resolved2.command,resolved2.args,{stdio:["pipe","pipe","ignore"],env,box:{allowEnv}})}catch{return resolve35([])}let settled=!1,timer2,hardKillTimer,done=out=>{
|
|
7768
7772
|
if(!settled){settled=!0,timer2&&clearTimeout(timer2);try{child.kill()&&(hardKillTimer=setTimeout(()=>{try{child.kill("SIGKILL")}catch{}},1e3),hardKillTimer.unref?.())}catch{}resolve35(out)}};timer2=setTimeout(()=>done([]),hermesAcpModelsTimeoutMs(env)),child.once("error",()=>done([])),child.stdin?.on("error",()=>done([])),child.once("close",()=>{hardKillTimer&&clearTimeout(hardKillTimer),done([])});let buf="",id=0,send2=(method,params)=>{id+=1;try{if(!child.stdin?.writable)return done([]),0;child.
|
|
7769
7773
|
stdin.write(`${JSON.stringify({jsonrpc:"2.0",id,method,params})}
|
|
7770
7774
|
`,error62=>{error62&&done([])})}catch{return done([]),0}return id},initId=0,sessionId=0;child.stdout?.on("data",chunk=>{buf+=String(chunk);let nl;for(;(nl=buf.indexOf(`
|
|
7771
|
-
`))>=0;){let line3=buf.slice(0,nl);buf=buf.slice(nl+1);let msg;try{msg=JSON.parse(line3)}catch{continue}if(msg?.id===initId){if(!msg.result)return done([]);sessionId=send2("session/new",{cwd:env.HOME||env.USERPROFILE||
|
|
7775
|
+
`))>=0;){let line3=buf.slice(0,nl);buf=buf.slice(nl+1);let msg;try{msg=JSON.parse(line3)}catch{continue}if(msg?.id===initId){if(!msg.result)return done([]);sessionId=send2("session/new",{cwd:env.HOME||env.USERPROFILE||homedir26(),mcpServers:[]})}else if(sessionId&&msg?.id===sessionId){let list5=Array.isArray(msg.result?.models?.availableModels)?msg.result.models.availableModels:[];done(list5.filter(m3=>typeof m3?.modelId=="string"&&m3.modelId).map(m3=>({id:m3.modelId,label:typeof m3.name=="strin\
|
|
7772
7776
|
g"&&m3.name.trim()||m3.modelId,custom:!0})))}}}),initId=send2("initialize",{protocolVersion:1,clientCapabilities:{fs:{readTextFile:!1,writeTextFile:!1}}})})}async function resolveHermesModels(env,config3,allowEnv=[]){let cli=config3?.cli||"hermes",catalog=await mergeLocalInject(EMPTY2,env),configured=hermesConfiguredModel(env),remote=configured?await fetchHermesAcpModels(cli,env,allowEnv):[],seen=new Set,options2=[...configured?[configured]:[],...remote,...catalog.options].filter(o=>seen.has(o.id)?
|
|
7773
7777
|
!1:(seen.add(o.id),!0));return!options2.length&&!hermesUsesProbedProvider(env)&&hermesInstalled(cli)&&options2.push(hermesConfigOption("")),{default:options2[0]?.id??"",options:options2}}async function applySetting2(request2,method,params,what){try{await request2(method,params)}catch(e){throw new Error(`Hermes rejected ${what} via ${method}: ${e.message}`)}}function hermesSteerAnswer(chunk){return HERMES_STEER_ANSWERS.find(([line3])=>chunk.startsWith(line3))?.[1]??null}var EMPTY2,HERMES_OPENMAUS_SCREENSHOT_COMPAT,
|
|
7774
7778
|
HERMES_OPENMAUS_SCREENSHOT_COMPAT_MODEL,HERMES_CONFIG_MODEL_ID,HERMES_HOSTED_PROVIDER_KEYS,HERMES_LOCAL_CONFIG_PROVIDERS,HERMES_PROBED_PROVIDERS,PROBED_LOOPBACK_HOSTS,HERMES_ACP_MODELS_TIMEOUT_ENV,HERMES_ACP_MODELS_DEFAULT_TIMEOUT_MS,HERMES_STEER_ANSWERS,support10,HermesAgentDriver,init_hermes=__esm({"server/drivers/acp/hermes.ts"(){"use strict";init_browser2();init_env_path();init_procs();init_local_inject();init_core3();EMPTY2={default:"",options:[]},HERMES_OPENMAUS_SCREENSHOT_COMPAT="HERMES_O\
|
|
@@ -7777,10 +7781,10 @@ MS",HERMES_ACP_MODELS_DEFAULT_TIMEOUT_MS=15e3;HERMES_STEER_ANSWERS=[["\u23E9 Ste
|
|
|
7777
7781
|
model,env),model)),defaultCli:"hermes",nativeSource:"hermes.acp",loginNote:"Hermes CLI is not installed",install:{command:{darwin:"curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash",linux:"curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash",win32:"iex (irm https://hermes-agent.nousresearch.com/install.ps1)"},docsUrl:"https://hermes-agent.nousresearch.com/docs/getting-started/quickstart",signInCommand:"hermes setup"},spawnArgs:()=>["acp"],restartOnMcpChange:!0,resendsReasoningReply:!0,
|
|
7778
7782
|
steer:{command:"steer",answer:hermesSteerAnswer},transformEnv:env=>{delete env.OPENAI_API_KEY,delete env.OPENROUTER_API_KEY},pickAuthMethod:()=>null,authFailure:"continue",isAuthenticated:()=>!0,async configureSession({request:request2,sessionId,turn}){let native=hermesAcpModelId(turn.model);native&&await applySetting2(request2,"session/set_model",{sessionId,modelId:native},`model "${native}"`)},buildPromptText:turn=>turn.system?`${turn.system}
|
|
7779
7783
|
|
|
7780
|
-
${turn.text}`:turn.text},HermesAgentDriver=createAcpDriver(support10)}});import{readFileSync as
|
|
7781
|
-
return typeof provider!="string"||typeof model!="string"||!provider||!model?null:`${provider}/${model}`}function dshHome(env){return env.DSH_HOME||harnessHome("dsh",env)}function storedCredentialPresent(path3){let doc;try{doc=parse4(
|
|
7782
|
-
try{text13=
|
|
7783
|
-
|
|
7784
|
+
${turn.text}`:turn.text},HermesAgentDriver=createAcpDriver(support10)}});import{readFileSync as readFileSync52}from"node:fs";import{tmpdir as tmpdir13}from"node:os";import{join as join93}from"node:path";function deepseekWireValue(pickerId){let slash=pickerId.indexOf("/");return slash<=0||slash===pickerId.length-1?pickerId:JSON.stringify([pickerId.slice(0,slash),pickerId.slice(slash+1)])}function deepseekPickerId(wireValue){let parsed;try{parsed=JSON.parse(wireValue)}catch{return null}if(!Array.isArray(parsed)||parsed.length!==2)return null;let[provider,model]=parsed;
|
|
7785
|
+
return typeof provider!="string"||typeof model!="string"||!provider||!model?null:`${provider}/${model}`}function dshHome(env){return env.DSH_HOME||harnessHome("dsh",env)}function storedCredentialPresent(path3){let doc;try{doc=parse4(readFileSync52(path3,"utf8"))}catch{return!1}if(!doc||typeof doc!="object")return!1;let root=doc,refs=root.refs&&typeof root.refs=="object"?root.refs:{};return nonEmpty2(refs.DEEPSEEK_API_KEY)||nonEmpty2(root.DEEPSEEK_API_KEY)}function dotenvValuePresent(path3){let text13;
|
|
7786
|
+
try{text13=readFileSync52(path3,"utf8")}catch{return!1}for(let line3 of text13.split(/\r?\n/)){let match=DOTENV_LINE.exec(line3);if(!match)continue;let value=match[1].trim(),quoted2=/^(["'])(.*)\1(?:[ \t]+#.*)?$/.exec(value);if(quoted2?value=quoted2[2]:value=value.replace(/[ \t]+#.*$/,"").trim(),value!=="")return!0}return!1}function hasDeepSeekKey(env){if(nonEmpty2(env.DEEPSEEK_API_KEY))return!0;let home2=dshHome(env);return storedCredentialPresent(join93(home2,".credentials.yaml"))||dotenvValuePresent(
|
|
7787
|
+
join93(home2,".env"))}function offeredWireValues(sessionConfig,configId){let options2=sessionConfig?.configOptions,option=(Array.isArray(options2)?options2:[]).find(entry=>entry?.id===configId),values=[],collect=entries2=>{if(Array.isArray(entries2))for(let entry of entries2)typeof entry?.value=="string"?values.push(entry.value):Array.isArray(entry?.options)&&collect(entry.options)};return collect(option?.options),{values,current:typeof option?.currentValue=="string"?option.currentValue:null}}function parseDeepSeekCatalog(sessionResult){
|
|
7784
7788
|
let options2=sessionResult?.configOptions,option=(Array.isArray(options2)?options2:[]).find(entry=>entry?.id==="model"),out=[],collect=(entries2,provider)=>{if(Array.isArray(entries2))for(let entry of entries2){if(Array.isArray(entry?.options)){let name=typeof entry.name=="string"&&entry.name.trim()?entry.name.trim():typeof entry.group=="string"?entry.group:provider;collect(entry.options,name);continue}if(typeof entry?.value!="string")continue;let id=deepseekPickerId(entry.value);if(!id||out.some(
|
|
7785
7789
|
row=>row.id===id))continue;let label2=typeof entry.name=="string"&&entry.name.trim()?entry.name.trim():id;out.push({id,label:label2,...provider?{provider}:{}})}};if(collect(option?.options,void 0),!out.length)throw new Error("dsh advertised no models");let current=typeof option?.currentValue=="string"?deepseekPickerId(option.currentValue):null;return{default:current&&out.some(row=>row.id===current)?current:out[0].id,options:out}}function catalogTimeoutMs(env){let raw=env[DEEPSEEK_MODELS_TIMEOUT_ENV];
|
|
7786
7790
|
if(raw===void 0)return DEEPSEEK_MODELS_DEFAULT_TIMEOUT_MS;let parsed=Number(raw);return Number.isInteger(parsed)&&parsed>0&&parsed<=2147483647?parsed:DEEPSEEK_MODELS_DEFAULT_TIMEOUT_MS}function fetchDeepSeekCatalog(cli,env,cwd,allowEnv=[]){return new Promise((resolve35,reject)=>{let child;try{let resolved2=resolveCli(cli,["--profile","acp"],env);child=spawnCli(resolved2.command,resolved2.args,{stdio:["pipe","pipe","ignore"],env,box:{allowEnv}})}catch(error62){return reject(error62 instanceof Error?
|
|
@@ -7794,19 +7798,19 @@ deepseekSupport,DeepSeekAgentDriver,init_deepseek=__esm({"server/drivers/acp/dee
|
|
|
7794
7798
|
pseek-ai/dsh",linux:"npm install -g @deepseek-ai/dsh",win32:"npm install -g @deepseek-ai/dsh"},docsUrl:"https://github.com/deepseek-ai/deepseek-harness",needsNode:!0,settings:"connections"},spawnArgs:()=>["--profile","acp"],credentialEnv:["DEEPSEEK_API_KEY"],selectModel:{configId:"model"},modelVariants:!0,resumeMethod:"resume",restartOnMcpChange:!0,resolveModels:(env,config3,_instanceId,_fresh,allowEnv)=>fetchDeepSeekCatalog(config3.cli||"dsh",env,tmpdir13(),allowEnv),resolveModelsOnCreate:!1,pickAuthMethod:()=>null,
|
|
7795
7799
|
authFailure:"continue",isAuthenticated:env=>hasDeepSeekKey(env),resolveTurnModel:model=>model&&deepseekWireValue(model),fallbackModel:(sessionConfig,catalogDefault)=>{let{values,current}=offeredWireValues(sessionConfig,"model"),wanted=catalogDefault?deepseekWireValue(catalogDefault):"";return wanted&&values.includes(wanted)?wanted:current&&values.includes(current)?current:null},buildPromptText:turn=>turn.system?`${turn.system}
|
|
7796
7800
|
|
|
7797
|
-
${turn.text}`:turn.text},DeepSeekAgentDriver=createAcpDriver(deepseekSupport)}});import{mkdtempSync as mkdtempSync10,readFileSync as
|
|
7798
|
-
find(arg=>arg.startsWith(`${name}=`))?.slice(name.length+1)},home2=flag3("--config")||env.CLINE_DIR||
|
|
7801
|
+
${turn.text}`:turn.text},DeepSeekAgentDriver=createAcpDriver(deepseekSupport)}});import{mkdtempSync as mkdtempSync10,readFileSync as readFileSync53,renameSync as renameSync12,rmSync as rmSync26,statSync as statSync24,writeFileSync as writeFileSync25}from"node:fs";import{homedir as homedir27,tmpdir as tmpdir14}from"node:os";import{join as join94}from"node:path";import{createHash as createHash28}from"node:crypto";function savedProvider(env,config3){try{let args=resolveCli(config3.cli,[],env).args,flag3=name=>{let index2=args.lastIndexOf(name);return index2>=0?args[index2+1]:args.
|
|
7802
|
+
find(arg=>arg.startsWith(`${name}=`))?.slice(name.length+1)},home2=flag3("--config")||env.CLINE_DIR||join94(env.HOME||env.USERPROFILE||homedir27(),".cline"),data=flag3("--data-dir")||env.CLINE_DATA_DIR||join94(home2,"data"),path3=env.CLINE_PROVIDER_SETTINGS_PATH||join94(data,"settings","providers.json");if(statSync24(path3).size>256*1024)return null;let text13=readFileSync53(path3,"utf8"),stored=JSON.parse(text13);if(stored?.version!==1||!stored.providers||Array.isArray(stored.providers))return null;
|
|
7799
7803
|
let provider=env.CLINE_PROVIDER||stored.lastUsedProvider;if(typeof provider!="string"||!/^[\w.-]{1,100}$/.test(provider))return null;let settings2=stored.providers[provider]?.settings;if(!settings2||settings2.provider!==provider)return null;for(let name of["model","apiKey"])if(settings2[name]!==void 0&&typeof settings2[name]!="string")return null;if(settings2.auth!==void 0){if(!settings2.auth||typeof settings2.auth!="object"||Array.isArray(settings2.auth))return null;for(let name of["accessToken",
|
|
7800
7804
|
"apiKey"])if(settings2.auth[name]!==void 0&&typeof settings2.auth[name]!="string")return null}return{settings:settings2,fingerprint:createHash28("sha256").update(text13).digest("hex")}}catch{return null}}var MODELS3,OAUTH,LOGIN_NOTE,SUPPORT,ClineAgentDriver,init_cline=__esm({"server/drivers/acp/cline.ts"(){"use strict";init_procs();init_core3();MODELS3={default:"cline-default",options:[{id:"cline-default",label:"Cline default (configured)"}]};OAUTH=new Set(["cline","cline-pass","openai-codex"]),
|
|
7801
7805
|
LOGIN_NOTE="Cline is not configured. Run cline auth in a terminal, then try again.",SUPPORT={driverKind:"clineAgent",displayName:"Cline",models:MODELS3,defaultCli:"cline",nativeSource:"cline.acp",images:!0,loginNote:LOGIN_NOTE,install:{command:{darwin:"npm install -g cline",linux:"npm install -g cline",win32:"npm install -g cline"},needsNode:!0,docsUrl:"https://docs.cline.bot/usage/acp",signInCommand:"cline auth"},spawnArgs:()=>["--acp","--auto-approve","false"],restartOnMcpChange:!0,credentialEnv:[
|
|
7802
7806
|
"CLINE_API_KEY"],transformEnv(env,config3){let saved=savedProvider(env,config3)?.settings;saved&&(env.CLINE_PROVIDER||=saved.provider,env.CLINE_MODEL||=saved.model,OAUTH.has(saved.provider)||(env.CLINE_API_KEY||=saved.apiKey||saved.auth?.apiKey))},spawnFingerprint:(env,config3)=>savedProvider(env,config3)?.fingerprint??"unconfigured",pickAuthMethod:(methods,env)=>!env.CLINE_API_KEY&&OAUTH.has(env.CLINE_PROVIDER??"")&&methods.some(method=>method.id===env.CLINE_PROVIDER)?env.CLINE_PROVIDER:null,authFailure:"\
|
|
7803
7807
|
fail-request",isAuthenticated:(env,config3)=>{if(env.CLINE_API_KEY?.trim())return!0;let saved=savedProvider(env,config3)?.settings;return!!(saved&&OAUTH.has(saved.provider)&&(saved.auth?.accessToken?.trim()||saved.apiKey?.trim()||saved.auth?.apiKey?.trim()))},requireAuthenticationBeforeSpawn:!0,resolveTurnModel(model,env){if(model&&model!=="cline-default")throw new Error("Select Cline default (configured). Change Cline's provider or model with cline auth in a terminal.");return env.CLINE_MODEL?.
|
|
7804
|
-
trim()},async configureSession({request:request2,sessionId,env,currentModelId}){let model=env.CLINE_MODEL?.trim();model&&model!==currentModelId&&await request2("session/set_model",{sessionId,modelId:model})}},ClineAgentDriver={...createAcpDriver(SUPPORT),async create(input2){let directory=mkdtempSync10(
|
|
7805
|
-
threadId,mcpServers}){let path3=
|
|
7806
|
-
.next`,text13,{mode:384}),renameSync12(`${path3}.next`,path3)),env.CLINE_MCP_SETTINGS_PATH=path3}}).create(input2),dispose=instance.dispose;return instance.dispose=async()=>{try{await dispose()}finally{cleanup()}},instance}catch(error62){throw cleanup(),error62}}}}});import{createHash as createHash29}from"node:crypto";import{mkdtemp as mkdtemp4,readFile as readFile7,realpath as realpath3,rm as rm6}from"node:fs/promises";import{homedir as
|
|
7807
|
-
configOptions2)?configOptions2.map(record10).find(entry=>entry?.type==="select"&&(entry.id==="model"||entry.category==="model")):void 0,values=Array.isArray(option?.options)?option.options.map(record10):[],usage2=record10(values.find(value=>value?.value===model.id)?._meta)?.copilotUsage;return typeof usage2=="string"&&/^\d+(?:\.\d+)?x$/.test(usage2)?`${model.label} \xB7 ${usage2}`:model.label}function copilotHome(env){return env.COPILOT_HOME||
|
|
7808
|
-
HOME)||
|
|
7809
|
-
form))}async function forgetCopilotDiscoverySession({sessionId,cwd,env}){if(!/^[\w-]{1,128}$/.test(sessionId))return;let folder=
|
|
7808
|
+
trim()},async configureSession({request:request2,sessionId,env,currentModelId}){let model=env.CLINE_MODEL?.trim();model&&model!==currentModelId&&await request2("session/set_model",{sessionId,modelId:model})}},ClineAgentDriver={...createAcpDriver(SUPPORT),async create(input2){let directory=mkdtempSync10(join94(tmpdir14(),"omb-cline-mcp-")),cleanup=()=>{try{rmSync26(directory,{recursive:!0,force:!0,maxRetries:5,retryDelay:100})}catch{}};try{let instance=await createAcpDriver({...SUPPORT,applyTurnEnv(env,{
|
|
7809
|
+
threadId,mcpServers}){let path3=join94(directory,`${createHash28("sha256").update(threadId).digest("hex")}.json`),mcp=Object.fromEntries(mcpServers.flatMap(server=>"command"in server?[server]:[]).map(({name,command,args,env:serverEnv})=>[name,{transport:{type:"stdio",command,args,env:Object.fromEntries(serverEnv.map(({name:name2,value})=>[name2,value]))}}])),text13=JSON.stringify({mcpServers:mcp}),previous2;try{previous2=readFileSync53(path3,"utf8")}catch{}previous2!==text13&&(writeFileSync25(`${path3}\
|
|
7810
|
+
.next`,text13,{mode:384}),renameSync12(`${path3}.next`,path3)),env.CLINE_MCP_SETTINGS_PATH=path3}}).create(input2),dispose=instance.dispose;return instance.dispose=async()=>{try{await dispose()}finally{cleanup()}},instance}catch(error62){throw cleanup(),error62}}}}});import{createHash as createHash29}from"node:crypto";import{mkdtemp as mkdtemp4,readFile as readFile7,realpath as realpath3,rm as rm6}from"node:fs/promises";import{homedir as homedir28,tmpdir as tmpdir15}from"node:os";import{join as join95,resolve as resolve28}from"node:path";function record10(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)?value:void 0}function copilotModelLabel(model,sessionNew){let configOptions2=record10(sessionNew)?.configOptions,option=Array.isArray(
|
|
7811
|
+
configOptions2)?configOptions2.map(record10).find(entry=>entry?.type==="select"&&(entry.id==="model"||entry.category==="model")):void 0,values=Array.isArray(option?.options)?option.options.map(record10):[],usage2=record10(values.find(value=>value?.value===model.id)?._meta)?.copilotUsage;return typeof usage2=="string"&&/^\d+(?:\.\d+)?x$/.test(usage2)?`${model.label} \xB7 ${usage2}`:model.label}function copilotHome(env){return env.COPILOT_HOME||join95((process.platform==="win32"?env.USERPROFILE:env.
|
|
7812
|
+
HOME)||homedir28(),".copilot")}function yamlScalar(value){let quoted2=/^(["'])(.*)\1$/.exec(value);return quoted2?quoted2[1]==="'"?quoted2[2].replaceAll("''","'"):quoted2[2].replace(/\\(["\\])/g,"$1"):value}async function sameFolder(recorded,cwd){let forms=async path3=>{let all2=[resolve28(path3)];try{all2.push(await realpath3(path3))}catch{}return all2.map(form=>process.platform==="win32"?form.toLowerCase():form)},ours=new Set(await forms(cwd));return(await forms(recorded)).some(form=>ours.has(
|
|
7813
|
+
form))}async function forgetCopilotDiscoverySession({sessionId,cwd,env}){if(!/^[\w-]{1,128}$/.test(sessionId))return;let folder=join95(copilotHome(env),"session-state",sessionId),workspace;try{workspace=await readFile7(join95(folder,"workspace.yaml"),"utf8")}catch{return}let field=name=>{let value=new RegExp(`^${name}:[ \\t]*(.*?)[ \\t]*$`,"m").exec(workspace)?.[1];return value===void 0?void 0:yamlScalar(value)},recorded=field("cwd");!recorded||field("client_name")!==DISCOVERY_CLIENT_NAME||!await sameFolder(
|
|
7810
7814
|
recorded,cwd)||await rm6(folder,{recursive:!0,force:!0,maxRetries:5,retryDelay:100})}function rememberSignIn(key2,answer){let signedIn=answer.then(value=>value.signedIn);return signIns.set(key2,{signedIn,until:Number.POSITIVE_INFINITY}),answer.then(({signedIn:value,forMs})=>{lastSignIns.set(key2,value),signIns.get(key2)?.signedIn===signedIn&&signIns.set(key2,{signedIn,until:Date.now()+forMs})}),signedIn}function resolveCopilotModels(env,config3){let catalog=discoverAcpModels(env,config3.cli,SPAWN_ARGS,
|
|
7811
7815
|
DISCOVERY);return rememberSignIn(signInKey(env,config3.cli),signedInAfter(catalog)),catalog}function copilotSignedIn(env,config3,waitMs=SIGN_IN_WAIT_MS){let key2=signInKey(env,config3.cli),cached4=signIns.get(key2),probe=cached4&&cached4.until>Date.now()?cached4.signedIn:rememberSignIn(key2,signedInAfter(discoverAcpModels(env,config3.cli,SPAWN_ARGS,{...DISCOVERY,variants:!1})));return new Promise(done=>{let timer2=setTimeout(()=>done(lastSignIns.get(key2)??!0),waitMs);probe.then(signedIn=>{clearTimeout(
|
|
7812
7816
|
timer2),done(signedIn)})})}function classifyCopilotError(error62){let value=record10(error62),text13=`${typeof value?.message=="string"?value.message:""}`.toLowerCase();return value?.code===-32e3&&LOGIN_REFUSAL.test(text13)&&!MCP_SERVER.test(text13)?"invalid_credentials":void 0}function describeCopilotAccountError(code){return code==="invalid_credentials"?LOGIN_NOTE2:"GitHub Copilot refused this request for the signed-in account. Check its Copilot plan and premium request allowance, then try aga\
|
|
@@ -7819,19 +7823,19 @@ ilot/reference/acp-server",signInCommand:SIGN_IN2},spawnArgs:()=>SPAWN_ARGS,tran
|
|
|
7819
7823
|
let offered=offeredModels(sessionConfig,"model");return offered.includes(catalogDefault)?catalogDefault:offered.includes(AUTO)?AUTO:null},restartOnMcpChange:!0,mcpServersFromLaunch:!0,pickAuthMethod:()=>null,authFailure:"continue",isAuthenticated:(env,config3)=>copilotSignedIn(env,config3),classifyError:classifyCopilotError,describeAccountError:describeCopilotAccountError,accountErrorText:code=>code==="invalid_credentials"?void 0:{key:"chat.notice.copilotAccountRefused"},buildPromptText:turn=>turn.
|
|
7820
7824
|
system?`${turn.system}
|
|
7821
7825
|
|
|
7822
|
-
${turn.text}`:turn.text},CopilotAgentDriver={...createAcpDriver(SUPPORT2),async create(input2){let directory=await mkdtemp4(
|
|
7826
|
+
${turn.text}`:turn.text},CopilotAgentDriver={...createAcpDriver(SUPPORT2),async create(input2){let directory=await mkdtemp4(join95(tmpdir15(),"omb-copilot-mcp-")),cleanup=()=>rm6(directory,{recursive:!0,force:!0,maxRetries:5,retryDelay:100});try{let instance=await createAcpDriver({...SUPPORT2,applyTurnEnv(env,{threadId,mcpServers}){let path3=join95(directory,`${createHash29("sha256").update(threadId).digest("hex")}.json`),servers=Object.fromEntries(mcpServers.map(server=>[server.name,"command"in
|
|
7823
7827
|
server?{type:"local",command:server.command,args:server.args,env:Object.fromEntries(server.env.map(({name,value})=>[name,value])),tools:["*"]}:{type:server.type,url:server.url,headers:Object.fromEntries(server.headers.map(({name,value})=>[name,value])),tools:["*"]}]));writeFileAtomicIfChanged(path3,JSON.stringify({mcpServers:servers}),{mode:384,durable:!1}),env.OMB_COPILOT_MCP_CONFIG=path3},resolveCommand(env,config3){let path3=env.OMB_COPILOT_MCP_CONFIG;if(!path3)throw new Error("GitHub Copilot\
|
|
7824
|
-
's tool configuration was not prepared.");return Promise.resolve({command:config3.cli,args:["--additional-mcp-config",`@${path3}`]})}}).create(input2),dispose=instance.dispose;return instance.dispose=async()=>{try{await dispose()}finally{await cleanup()}},instance}catch(error62){throw await cleanup(),error62}}}}});import{readFileSync as
|
|
7825
|
-
""}catch{return!1}}async function forgetCommandCodeDiscoverySession({sessionId,env}){if(!/^[\w-]{1,128}$/.test(sessionId))return;let projects=
|
|
7826
|
-
{force:!0}))),await rmdir(
|
|
7828
|
+
's tool configuration was not prepared.");return Promise.resolve({command:config3.cli,args:["--additional-mcp-config",`@${path3}`]})}}).create(input2),dispose=instance.dispose;return instance.dispose=async()=>{try{await dispose()}finally{await cleanup()}},instance}catch(error62){throw await cleanup(),error62}}}}});import{readFileSync as readFileSync54}from"node:fs";import{readdir as readdir6,rm as rm7,rmdir}from"node:fs/promises";import{join as join96}from"node:path";function commandCodeAuthFile(env){return join96(userHome(env),".commandcode",AUTH_FILES2[env.COMMANDCODE_API_ENV??""]??AUTH_FILES2.prod)}function commandCodeSignedIn(env){if(env[API_KEY_ENV]?.trim())return!0;try{let stored=JSON.parse(readFileSync54(commandCodeAuthFile(env),"utf8"));return typeof stored?.apiKey=="string"&&stored.apiKey.trim()!==
|
|
7829
|
+
""}catch{return!1}}async function forgetCommandCodeDiscoverySession({sessionId,env}){if(!/^[\w-]{1,128}$/.test(sessionId))return;let projects=join96(userHome(env),".commandcode","projects"),folders=await readdir6(projects).catch(()=>[]);for(let folder of folders.filter(name=>name.includes("omb-acp-models-"))){let ours=(await readdir6(join96(projects,folder)).catch(()=>[])).filter(name=>name.startsWith(`${sessionId}.`));ours.length&&(await Promise.all(ours.map(name=>rm7(join96(projects,folder,name),
|
|
7830
|
+
{force:!0}))),await rmdir(join96(projects,folder)).catch(()=>{}))}}function resolveCommandCodeModels(env,config3){return discoverAcpModels(env,config3.cli,SPAWN_ARGS2,DISCOVERY2)}function classifyCommandCodeError(error62){let value=error62!==null&&typeof error62=="object"?error62:void 0,text13=typeof value?.message=="string"?value.message.toLowerCase():"";return value?.code===-32e3&&/\bnot authenticated\b|\bcmd login\b/.test(text13)?"invalid_credentials":void 0}function describeCommandCodeAccountError(code){
|
|
7827
7831
|
return code==="invalid_credentials"?LOGIN_NOTE3:"Command Code refused this request for the signed-in account. Check its plan and credits on commandcode.ai, then try again."}var AGENT_DEFAULT2,MODELS5,SPAWN_ARGS2,SIGN_IN3,API_KEY_ENV,LOGIN_NOTE3,MODE_ASK,MODE_FULL,AUTH_FILES2,DISCOVERY2,SUPPORT3,CommandCodeAgentDriver,init_command_code=__esm({"server/drivers/acp/command-code.ts"(){"use strict";init_env_path();init_core3();init_custom_model_catalog();AGENT_DEFAULT2={id:"agent-default",label:"Comma\
|
|
7828
7832
|
nd Code default"},MODELS5={default:AGENT_DEFAULT2.id,options:[AGENT_DEFAULT2]},SPAWN_ARGS2=["acp"],SIGN_IN3="cmd login",API_KEY_ENV="COMMAND_CODE_API_KEY",LOGIN_NOTE3=`Command Code is not signed in. Run ${SIGN_IN3} in a terminal, or set ${API_KEY_ENV}, then check again.`,MODE_ASK="default",MODE_FULL="bypass",AUTH_FILES2={prod:"auth.json",staging:"auth.staging.json",local:"auth.local.json"};DISCOVERY2={passthrough:AGENT_DEFAULT2,exitGraceMs:1e3,forgetSession:forgetCommandCodeDiscoverySession};SUPPORT3=
|
|
7829
7833
|
{driverKind:"commandCodeAgent",displayName:"Command Code",models:MODELS5,defaultCli:"command-code",nativeSource:"command-code.acp",images:!0,loginNote:LOGIN_NOTE3,install:{command:{darwin:"npm install -g command-code",linux:"npm install -g command-code",win32:"npm install -g command-code"},needsNode:!0,docsUrl:"https://commandcode.ai/docs/acp",signInCommand:SIGN_IN3},spawnArgs:()=>SPAWN_ARGS2,credentialEnv:[API_KEY_ENV],resolveModels:(env,config3)=>resolveCommandCodeModels(env,config3),resolveModelsOnCreate:!1,
|
|
7830
7834
|
selectModel:{configId:"model",agentDefault:AGENT_DEFAULT2.id},modelVariants:!0,pickAuthMethod:()=>null,authFailure:"continue",isAuthenticated:env=>commandCodeSignedIn(env),classifyError:classifyCommandCodeError,describeAccountError:describeCommandCodeAccountError,accountErrorText:code=>code==="invalid_credentials"?void 0:{key:"chat.notice.commandCodeAccountRefused"},async configureSession({request:request2,sessionId,config:config3}){let modeId=config3.fullAuto?MODE_FULL:MODE_ASK;try{await request2(
|
|
7831
7835
|
"session/set_mode",{sessionId,modeId})}catch(error62){throw new Error(`Command Code rejected permission mode "${modeId}": ${error62.message}`)}},buildPromptText:turn=>turn.system?`${turn.system}
|
|
7832
7836
|
|
|
7833
|
-
${turn.text}`:turn.text},CommandCodeAgentDriver=createAcpDriver(SUPPORT3)}});import{DatabaseSync as DatabaseSync4}from"node:sqlite";import{join as
|
|
7834
|
-
trim())return!0;let db;try{return db=new DatabaseSync4(
|
|
7837
|
+
${turn.text}`:turn.text},CommandCodeAgentDriver=createAcpDriver(SUPPORT3)}});import{DatabaseSync as DatabaseSync4}from"node:sqlite";import{join as join97}from"node:path";function kiroDataDir(env,platform=process.platform){let home2=userHome(env);return platform==="darwin"?join97(home2,"Library","Application Support","kiro-cli"):platform==="win32"?join97(env.LOCALAPPDATA?.trim()||join97(home2,"AppData","Local"),"kiro-cli"):join97(env.XDG_DATA_HOME?.trim()||join97(home2,".local","share"),"kiro-cli")}function kiroSignedIn(env,platform=process.platform){if(env[API_KEY_ENV2]?.
|
|
7838
|
+
trim())return!0;let db;try{return db=new DatabaseSync4(join97(kiroDataDir(env,platform),"data.sqlite3"),{readOnly:!0}),db.prepare("SELECT 1 FROM auth_kv WHERE key LIKE '%:token' AND length(value) > 0 LIMIT 1").get()!==void 0}catch{return!1}finally{db?.close()}}function resolveKiroModels(env,config3){return discoverAcpModels(env,config3.cli,SPAWN_ARGS3,DISCOVERY3)}function kiroUpdateFilter(){let hiddenTools=new Set;return update=>{let toolCallId=typeof update.toolCallId=="string"?update.toolCallId:
|
|
7835
7839
|
"";if(update._meta?.kiro?.toolId===CLOUD_CONFIG_TOOL)return toolCallId&&update.status!=="completed"&&update.status!=="failed"?hiddenTools.add(toolCallId):hiddenTools.delete(toolCallId),null;if(toolCallId&&hiddenTools.has(toolCallId))return(update.status==="completed"||update.status==="failed")&&hiddenTools.delete(toolCallId),null;let text13=update.sessionUpdate==="agent_message_chunk"?update.content?.text:void 0;if(typeof text13!="string"||!text13.includes(STEERING_ECHO))return update;let kept=text13.
|
|
7836
7840
|
slice(0,text13.indexOf(STEERING_ECHO)).trimEnd();return kept?{...update,content:{...update.content,text:kept}}:null}}function describeKiroAccountError(code){return code==="invalid_credentials"?LOGIN_NOTE4:"Kiro refused this request for the signed-in account. Check its Kiro plan and credits, then try again."}var AGENT_DEFAULT3,MODELS6,SPAWN_ARGS3,SIGN_IN4,API_KEY_ENV2,LOGIN_NOTE4,AUTH_METHODS,CLIENT_META,CLOUD_CONFIG_TOOL,STEERING_ECHO,DISCOVERY3,SUPPORT4,KiroAgentDriver,init_kiro=__esm({"server/\
|
|
7837
7841
|
drivers/acp/kiro.ts"(){"use strict";init_env_path();init_core3();init_custom_model_catalog();AGENT_DEFAULT3={id:"agent-default",label:"Kiro default"},MODELS6={default:AGENT_DEFAULT3.id,options:[AGENT_DEFAULT3]},SPAWN_ARGS3=["acp","--agent-engine=v3","--auth-method=cli"],SIGN_IN4="kiro-cli login",API_KEY_ENV2="KIRO_API_KEY",LOGIN_NOTE4=`Kiro is not signed in. Run ${SIGN_IN4} in a terminal, or set ${API_KEY_ENV2}, then check again.`,AUTH_METHODS=["aws-builder-id","aws-iam-identity-center","kiro-lo\
|
|
@@ -7894,21 +7898,21 @@ ompletions",outgoing:(_turn,messages2,model,tools)=>({model,messageCount:message
|
|
|
7894
7898
|
agents&&(servers.agents={...turn.integrations.agents}),turn.integrations?.phone&&(servers.phone={...turn.integrations.phone}),turn.integrations?.dweb&&(servers.dweb={command:process.execPath,args:[SPAWNED_PROXIES.dweb],env:{...NODE_ENV_FLAG2,DWEB_URL:turn.integrations.dweb.url}}),turn.integrations?.browser&&(servers.browser={...turn.integrations.browser});for(let name of["data","email","device"])turn.integrations?.[name]&&(servers[name]={...turn.integrations[name]});for(let[name,server]of Object.
|
|
7895
7899
|
entries(turn.integrations?.custom??{}))servers[name]={...server,scope:"custom"};for(let[name,server]of Object.entries(servers)){if(parsed.scope!==void 0&&!canUseMcpServer(parsed.scope,name)){delete servers[name];continue}let directory=remoteMcpSpec(server)!==void 0,stdio=gateServer({name,server,toolScope:parsed.scope,threadId:turn.threadId,nodeEnv:NODE_ENV_FLAG2,directory,...customServerGate(name,name in(turn.integrations?.custom??{}),turn.integrations?.customResultBudgets),apps:appMountFor(name,
|
|
7896
7900
|
turn)})??mcpStdioServer(server,{nodeEnv:NODE_ENV_FLAG2,...directory?{directory:{name}}:{}});if(!stdio)throw new Error("Pi MCP server configuration is invalid");let original=server;servers[name]={...stdio,...original.scope?{scope:original.scope}:{},...directory?{directory:!0}:{}}}return Object.keys(servers).length?servers:null}var NODE_ENV_FLAG2,init_pi_mcp_servers=__esm({"server/drivers/pi-mcp-servers.ts"(){"use strict";init_tool_scope();init_own_apps();init_mcp_gate_config();init_mcp_http();init_proxy_paths();
|
|
7897
|
-
NODE_ENV_FLAG2={ELECTRON_RUN_AS_NODE:"1"}}});import{readFileSync as
|
|
7898
|
-
`))!==-1;){let line3=buf.slice(0,nl);if(buf=buf.slice(nl+1),dropping){dropping=!1;continue}if(!(line3.length>PI_MAX_LINE||!line3.trim())&&onLine(line3))return}buf.length>PI_MAX_LINE&&(buf="",dropping=!0)}}function readPiPromptImages(turn){return(turn.images??[]).map(image=>({type:"image",data:
|
|
7901
|
+
NODE_ENV_FLAG2={ELECTRON_RUN_AS_NODE:"1"}}});import{readFileSync as readFileSync55}from"node:fs";function decodePiFrame(line3,chunks){let parsed;try{parsed=JSON.parse(line3)}catch{return null}if(!parsed||typeof parsed!="object"||Array.isArray(parsed))return null;let frame=parsed;return frame.type==="rpc_chunk"?chunks.accept(frame):frame}function piLineReader(onLine){let buf="",dropping=!1;return chunk=>{buf+=chunk;let nl;for(;(nl=buf.indexOf(`
|
|
7902
|
+
`))!==-1;){let line3=buf.slice(0,nl);if(buf=buf.slice(nl+1),dropping){dropping=!1;continue}if(!(line3.length>PI_MAX_LINE||!line3.trim())&&onLine(line3))return}buf.length>PI_MAX_LINE&&(buf="",dropping=!0)}}function readPiPromptImages(turn){return(turn.images??[]).map(image=>({type:"image",data:readFileSync55(image.path).toString("base64"),mimeType:image.mime}))}var PiRpcChunks,PI_MAX_LINE,init_pi_rpc=__esm({"server/drivers/pi-rpc.ts"(){"use strict";PiRpcChunks=class _PiRpcChunks{static MAX_BYTES=64*
|
|
7899
7903
|
1024*1024;static MAX_PIECE_BYTES=256*1024;static MAX_COUNT=_PiRpcChunks.MAX_BYTES/_PiRpcChunks.MAX_PIECE_BYTES;chunkId=null;count=0;byteLength=0;bytes=0;parts=[];accept(message5){let{chunkId,index:index2,count:count5,byteLength:byteLength2,data}=message5;if(typeof chunkId!="string"||chunkId.length===0||typeof data!="string"||data.length===0||data.length>Math.ceil(_PiRpcChunks.MAX_PIECE_BYTES/3)*4||!Number.isInteger(index2)||!Number.isInteger(count5)||!Number.isInteger(byteLength2)||index2<0||count5<
|
|
7900
7904
|
2||count5>_PiRpcChunks.MAX_COUNT||index2>=count5||byteLength2<0||byteLength2>_PiRpcChunks.MAX_BYTES)return this.reset(),null;if(chunkId!==this.chunkId){if(index2!==0)return this.reset(),null;this.chunkId=chunkId,this.count=count5,this.byteLength=byteLength2,this.parts=[],this.bytes=0}else if(count5!==this.count||byteLength2!==this.byteLength)return this.reset(),null;let part=Buffer.from(data,"base64");if(index2!==this.parts.length||part.length===0||part.length>_PiRpcChunks.MAX_PIECE_BYTES||this.
|
|
7901
7905
|
bytes+part.length>this.byteLength)return this.reset(),null;if(this.parts.push(part),this.bytes+=part.length,this.parts.length<this.count)return null;let complete=this.bytes===this.byteLength,text13=Buffer.concat(this.parts).toString("utf8");if(this.reset(),!complete)return null;try{let frame=JSON.parse(text13);return frame&&typeof frame=="object"&&!Array.isArray(frame)?frame:null}catch{return null}}reset(){this.chunkId=null,this.count=0,this.byteLength=0,this.bytes=0,this.parts=[]}};PI_MAX_LINE=
|
|
7902
7906
|
PiRpcChunks.MAX_BYTES}});var usageCount,PiRunUsage,init_pi_usage=__esm({"server/drivers/pi-usage.ts"(){"use strict";usageCount=value=>typeof value=="number"&&Number.isFinite(value)&&value>=0?value:void 0,PiRunUsage=class{usage;cost;counted=!1;add(usage2){if(!usage2||this.counted)return;this.counted=!0;let total=this.usage,cacheRead=usageCount(usage2.cacheRead),cachedInput=cacheRead===void 0?total?.cachedInput:(total?.cachedInput??0)+cacheRead;this.usage={input:(total?.input??0)+(usageCount(usage2.input)??0)+(cacheRead??
|
|
7903
|
-
0)+(usageCount(usage2.cacheWrite)??0),output:(total?.output??0)+(usageCount(usage2.output)??0),...cachedInput===void 0?{}:{cachedInput}};let cost2=usageCount(usage2.cost?.total);cost2&&(this.cost=(this.cost??0)+cost2)}endTurn(usage2){this.add(usage2),this.counted=!1}}}});import{chmodSync as chmodSync10,existsSync as
|
|
7907
|
+
0)+(usageCount(usage2.cacheWrite)??0),output:(total?.output??0)+(usageCount(usage2.output)??0),...cachedInput===void 0?{}:{cachedInput}};let cost2=usageCount(usage2.cost?.total);cost2&&(this.cost=(this.cost??0)+cost2)}endTurn(usage2){this.add(usage2),this.counted=!1}}}});import{chmodSync as chmodSync10,existsSync as existsSync38,mkdirSync as mkdirSync40,mkdtempSync as mkdtempSync11,readFileSync as readFileSync56,rmSync as rmSync27,writeFileSync as writeFileSync26}from"node:fs";import{homedir as homedir29,tmpdir as tmpdir16}from"node:os";import{join as join98}from"node:path";function piNativeLogMessage(message5){return Array.isArray(message5.images)?{...message5,images:message5.images.map(image=>{if(!image||typeof image!="object")return image;let value=image;return typeof value.
|
|
7904
7908
|
data=="string"?{...value,data:`[image data: ${value.data.length} base64 chars]`}:value})}:message5}function piThinkingLevel(effort){return effort==="none"?"off":effort}function piCatalogFromFrame(frame,fallbackDefault){let res=frame;if(res?.type!=="response"||res.command!=="get_available_models"||!res.success)return null;let options2=[];for(let m3 of res.data?.models??[]){if(!m3?.provider||!m3?.id)continue;let id=`${m3.provider}/${m3.id}`;options2.push({id,label:m3.name??m3.id,custom:!0,provider:m3.
|
|
7905
7909
|
provider})}return{default:fallbackDefault||(options2[0]?.id??""),options:options2}}function splitPiModel(id){let inject=decodeInjectId(id);if(inject)return{provider:inject.host,modelId:inject.model};if(!id.includes("/"))return null;let[provider,...rest]=id.split("/");return!provider||!rest.length?null:{provider,modelId:rest.join("/")}}function preferPiInjectRows(catalog){let injectIds=new Set(catalog.options.filter(option=>decodeInjectId(option.id)).map(option=>option.id));if(!injectIds.size)return catalog;
|
|
7906
7910
|
let options2=catalog.options.filter(option=>{if(decodeInjectId(option.id))return!0;let slash=option.id.indexOf("/");return slash<=0?!0:!injectIds.has(encodeInjectId(option.id.slice(0,slash),option.id.slice(slash+1)))}),def=catalog.default;if(def&&!options2.some(option=>option.id===def)){let slash=def.indexOf("/"),mapped2=slash>0?encodeInjectId(def.slice(0,slash),def.slice(slash+1)):"";def=injectIds.has(mapped2)?mapped2:options2[0]?.id??""}return{default:def,options:options2}}async function applyPiLocalCatalog(catalog,env=process.
|
|
7907
|
-
env,fetchImpl=fetch){return preferPiInjectRows(await mergeLocalInject(catalog,env,fetchImpl))}function piAgentDir(env){return
|
|
7908
|
-
on"),root={providers:{}};if(
|
|
7911
|
+
env,fetchImpl=fetch){return preferPiInjectRows(await mergeLocalInject(catalog,env,fetchImpl))}function piAgentDir(env){return join98(env.HOME||env.USERPROFILE||homedir29(),".pi","agent")}function ensurePiInjectModel(modelId2,env=process.env){let split=splitPiModel(modelId2);if(!split)return null;let inject=decodeInjectId(modelId2);if(!inject)return split;let host2=localHost(inject.host);if(!host2)return split;let dir=piAgentDir(env);mkdirSync40(dir,{recursive:!0});let path3=join98(dir,"models.js\
|
|
7912
|
+
on"),root={providers:{}};if(existsSync38(path3))try{let parsed=JSON.parse(readFileSync56(path3,"utf8"));if(parsed&&typeof parsed=="object"&&!Array.isArray(parsed))root=parsed;else return split}catch{return split}let providers=root.providers&&typeof root.providers=="object"&&!Array.isArray(root.providers)?{...root.providers}:{},previous2=providers[inject.host],existing=previous2&&typeof previous2=="object"&&!Array.isArray(previous2)?{...previous2}:{baseUrl:host2.baseUrl,api:"openai-completions",apiKey:hostApiKey(
|
|
7909
7913
|
host2,env),compat:{supportsDeveloperRole:!1,supportsReasoningEffort:!0},models:[]};existing.baseUrl=host2.baseUrl,existing.api=typeof existing.api=="string"&&existing.api?existing.api:"openai-completions",existing.apiKey=hostApiKey(host2,env),existing.compat||(existing.compat={supportsDeveloperRole:!1,supportsReasoningEffort:!0});let models2=Array.isArray(existing.models)?existing.models.filter(row=>!!row&&typeof row=="object"&&!Array.isArray(row)):[];models2.some(row=>row.id===inject.model)||models2.
|
|
7910
|
-
push({id:inject.model,name:inject.model,reasoning:!0,input:["text"],contextWindow:131072,maxTokens:16384}),existing.models=models2,providers[inject.host]=existing,root.providers=providers,
|
|
7911
|
-
`,{mode:384});try{chmodSync10(path3,384)}catch{}return split}function readPiDefaultModel(env){let home2=env.HOME||env.USERPROFILE||
|
|
7914
|
+
push({id:inject.model,name:inject.model,reasoning:!0,input:["text"],contextWindow:131072,maxTokens:16384}),existing.models=models2,providers[inject.host]=existing,root.providers=providers,writeFileSync26(path3,`${JSON.stringify(root,null,2)}
|
|
7915
|
+
`,{mode:384});try{chmodSync10(path3,384)}catch{}return split}function readPiDefaultModel(env){let home2=env.HOME||env.USERPROFILE||homedir29();try{let s4=JSON.parse(readFileSync56(`${home2}/.pi/agent/settings.json`,"utf8"));return s4.defaultProvider&&s4.defaultModel?`${s4.defaultProvider}/${s4.defaultModel}`:""}catch{return""}}async function fetchPiModels(cli,env,allowEnv=[]){let child=spawnCli(cli,PI_ARGS,{stdio:["pipe","pipe","pipe"],env,box:{allowEnv}});return new Promise(resolve35=>{let done=!1,
|
|
7912
7916
|
fallbackDefault=readPiDefaultModel(env),finish=catalog=>{if(!done){done=!0;try{killCliTree(child)}catch{}resolve35(catalog)}},timer2=setTimeout(()=>finish({default:"",options:[]}),15e3);timer2.unref?.();let chunks=new PiRpcChunks;child.stdout.setEncoding("utf8"),child.stdout.on("data",piLineReader(line3=>{let frame=decodePiFrame(line3,chunks);return frame?.command!=="get_available_models"?!1:(clearTimeout(timer2),finish(piCatalogFromFrame(frame,fallbackDefault)??{default:fallbackDefault,options:[]}),
|
|
7913
7917
|
!0)})),child.on("error",()=>finish({default:"",options:[]})),child.on("close",()=>finish({default:"",options:[]}));try{child.stdin.write(`${JSON.stringify(PI_NEGOTIATE_FRAME)}
|
|
7914
7918
|
`),child.stdin.write(JSON.stringify({id:"catalog",type:"get_available_models"})+`
|
|
@@ -7921,8 +7925,8 @@ catalogEnv));resolved2.options.length&&([base3,listed2]=[resolved2,!0])}catch{}t
|
|
|
7921
7925
|
{instanceId,use:catalog=>{models2=catalog},current:()=>models2,refresh:readModels}))?.pending??null,listeners2=new Set,active=new Map,stopAll=async()=>{let failure2=(await Promise.allSettled([...active.values()].map(({stop})=>Promise.resolve().then(stop)))).find(result2=>result2.status==="rejected");if(failure2)throw failure2.reason},emit=event=>{for(let l of Array.from(listeners2))l(event)},base2=(threadId,turnId)=>({eventId:newEventId(),provider:DRIVER_KIND5,providerInstanceId:instanceId,threadId,
|
|
7922
7926
|
turnId,createdAt:new Date().toISOString()}),sendTurn=async turn=>{startupModelRefresh&&await startupModelRefresh;let{threadId}=turn,selection=parseToolScope(turn.toolScope);if(!selection.ok)throw new Error(selection.error);let toolScope=selection.scope;if(active.has(threadId))throw new Error("a turn is already running on this thread");let fullAuto=turn.approvalMode===void 0?config3.fullAuto:!1;if(turn.integrations?.localComputer?.scope==="local-computer"&&fullAuto)throw new Error("local computer\
|
|
7923
7927
|
control requires the interactive approval broker");let turnId=newId(),pending=new Map,askTimers=new Set,settled=!1,completion=null,endStopReason,runUsage=new PiRunUsage,completionOutcome=null,endErrorMessage,agentEndTimer=null,images=readPiPromptImages(turn);typeof turn.model=="string"&&turn.model&&ensurePiInjectModel(turn.model,{...process.env,...input2.environment});let mcpServers=buildMcpServers(turn),askUser=toolScope===void 0||allowsTool(toolScope,{kind:"native",name:ASK_USER_TOOL}),mcpTempDir=mkdtempSync11(
|
|
7924
|
-
|
|
7925
|
-
pipe"],cwd:turn.cwd,env:piEnvironment({...process.env,...input2.environment,OMB_MCP_CONFIG:
|
|
7928
|
+
join98(tmpdir16(),"omb-pi-mcp-")),scopeReadyPath=toolScope!==void 0?join98(mcpTempDir,"scope-ready.json"):void 0;try{writeFileSync26(join98(mcpTempDir,"mcp.json"),JSON.stringify({mcpServers:mcpServers??{},toolScope,scopeReadyPath,approvalMode:turn.approvalMode,askUser}),{mode:384})}catch(err){try{rmSync27(mcpTempDir,{recursive:!0,force:!0})}catch{}throw err}let childArgs=[...PI_ARGS,"-e",SPAWNED_PROXIES.piMcpExtension],child=(()=>{try{return spawnCli(config3.cli,childArgs,{stdio:["pipe","pipe","\
|
|
7929
|
+
pipe"],cwd:turn.cwd,env:piEnvironment({...process.env,...input2.environment,OMB_MCP_CONFIG:join98(mcpTempDir,"mcp.json")})},"bot")}catch(err){try{rmSync27(mcpTempDir,{recursive:!0,force:!0})}catch{}throw err}})(),assistantText="",compactionObserved=!1,responseWaiters=new Map,steerSeq=0,rejectWaiters=err=>{for(let waiter of responseWaiters.values())clearTimeout(waiter.timer),waiter.reject(err);responseWaiters.clear()},awaitResponse=(command,timeoutMs=2e4,key2=command)=>new Promise((resolve35,reject)=>{
|
|
7926
7930
|
let timer2=timeoutMs===1/0?void 0:setTimeout(()=>{responseWaiters.delete(key2),reject(new Error(`pi ${command} timed out`))},timeoutMs);timer2?.unref?.(),responseWaiters.set(key2,{resolve:resolve35,reject,timer:timer2})});child.stdin.on("error",()=>rejectWaiters(new Error("pi stdin closed")));let send2=obj=>{appendNative(threadId,{dir:"out",source:"pi.rpc",msg:piNativeLogMessage(obj)}),child.stdin.write(JSON.stringify(obj)+`
|
|
7927
7931
|
`)};send2(PI_NEGOTIATE_FRAME);let flushAssistantText=()=>{let text13=assistantText;assistantText="",text13.trim()&&emit({...base2(threadId,turnId),type:"item.completed",itemType:"assistant_text",text:text13})},settle2=(ok2,stopReason,usage2=runUsage.usage)=>{if(completion)return completion;let outcome=completionOutcome??={ok:ok2,stopReason:stopReason??(ok2?"end_turn":"failed"),...usage2?{usage:usage2}:{},...runUsage.cost===void 0?{}:{cost:runUsage.cost}};settled=!0,agentEndTimer&&(clearTimeout(agentEndTimer),
|
|
7928
7932
|
agentEndTimer=null);for(let timer2 of askTimers)clearTimeout(timer2);askTimers.clear(),pending.clear();try{child.stdin.end()}catch{}return completion=(async()=>{if(!await killCliTree(child))throw new Error("Pi process termination could not be confirmed");rejectWaiters(new Error("pi turn ended"));try{rmSync27(mcpTempDir,{recursive:!0,force:!0})}catch{}active.delete(threadId),flushAssistantText(),emit({...base2(threadId,turnId),type:"turn.completed",...outcome})})(),completion.catch(error62=>{completion=
|
|
@@ -7941,7 +7945,7 @@ err,config3.cli,turn.cwd);rejectWaiters(new Error(fail3.message)),emit({...base2
|
|
|
7941
7945
|
try{let hsPromise=awaitResponse(sessionPath?"switch_session":"new_session",1/0);send2(sessionPath?{type:"switch_session",sessionPath}:{type:"new_session"});let slow=setTimeout(()=>emit({...base2(threadId,turnId),type:"runtime.notice",...noticeFailure("chat.notice.piSessionSlow")}),PI_SESSION_SLOW_MS),hs2=await hsPromise.finally(()=>clearTimeout(slow));hs2?.sessionFile&&(sessionFile=hs2.sessionFile),sessionId=sessionFile??hs2?.sessionId??null,sessionReady=!0,sessionOpened=!0}catch{}if(settled)return{
|
|
7942
7946
|
turnId};let chosen=typeof turn.model=="string"?splitPiModel(turn.model):null;if(chosen)try{let modelPromise=awaitResponse("set_model");if(send2({type:"set_model",provider:chosen.provider,modelId:chosen.modelId}),confirmedModel=piModelId(await modelPromise),!confirmedModel)throw new RuntimeNoticeError("Pi did not confirm the selected model","chat.notice.piModelNotConfirmed")}catch(error62){return settled||(emit({...base2(threadId,turnId),type:"runtime.error",message:String(error62.message),text:runtimeErrorText(
|
|
7943
7947
|
error62)}),await settle2(!1)),{turnId}}if(!chosen)try{let statePromise=awaitResponse("get_state");send2({type:"get_state"});let state=await statePromise;confirmedModel=piModelId(state?.model)}catch{}if(settled)return{turnId};if(sessionOpened&&emit({...base2(threadId,turnId),type:"session.started",sessionId,model:confirmedModel}),turn.effort)try{let levelPromise=awaitResponse("set_thinking_level");send2({type:"set_thinking_level",level:piThinkingLevel(turn.effort)}),await levelPromise}catch{}if(settled)
|
|
7944
|
-
return{turnId};if(scopeReadyPath){let ready=!1;try{let receipt=JSON.parse(
|
|
7948
|
+
return{turnId};if(scopeReadyPath){let ready=!1;try{let receipt=JSON.parse(readFileSync56(scopeReadyPath,"utf8"));ready=receipt.ok===!0&&JSON.stringify(receipt.toolScope)===JSON.stringify(toolScope)}catch{}if(!ready){let message6="Pi tool selection enforcement is unavailable. Update Pi and check the Limix Bot extension before retrying.";throw emit({...base2(threadId,turnId),type:"runtime.error",message:message6}),settle2(!1),new Error(message6)}}let halves=promptHalves(turn),message5,pendingReceipt=null;
|
|
7945
7949
|
if(halves.stable!==null&&sessionReady&&sessionFile){let receiptKey=JSON.stringify([threadId,sessionFile]),composed=splitSessionPrompt(halves.stable,halves.volatile,readPromptSplitReceipt("pi",receiptKey),turn.system,turn.text,!!turn.mentionTurn,PI_PROMPT_RE_ANCHOR_TURNS);message5=composed.text,pendingReceipt={key:receiptKey,receipt:composed.receipt}}else message5=turn.system?`${turn.system}
|
|
7946
7950
|
|
|
7947
7951
|
${turn.text}`:turn.text;try{let accepted=awaitResponse("prompt",12e4);send2({type:"prompt",message:message5,...images.length?{images}:{}}),accepted.then(()=>{if(!(!pendingReceipt||compactionObserved))try{writePromptSplitReceipt("pi",pendingReceipt.key,pendingReceipt.receipt)}catch{}},err=>{settled||(emit({...base2(threadId,turnId),type:"runtime.error",message:String(err?.message??err).slice(0,2e3)}),settle2(!1))})}catch(err){emit({...base2(threadId,turnId),type:"runtime.error",message:String(err?.
|
|
@@ -8047,7 +8051,7 @@ connection,target2,gap.after,paged),this.#options.discarded()||this.#options.fol
|
|
|
8047
8051
|
(paged.push(event),reached&&this.#servedTwins.add(cursor3))}if(result2.nextCursor===null){lastServed!==void 0&&(this.#cursor=lastServed);return}if(result2.events.length===0||typeof result2.nextCursor!="string"||result2.nextCursor===this.#cursor)throw new MuseGapFillError("pageStalled",after,target2);if(this.#cursor=result2.nextCursor,reached)return}}async#page(connection,cursor3){let params={cursor:cursor3,limit:PAGE_LIMIT,sessionId:this.#options.sessionId};return await connection.request("view/\
|
|
8048
8052
|
page",params)}#requireOwnSession(event,after,target2){let named2=event.params?.sessionId;if(typeof named2=="string"&&named2!==this.#options.sessionId)throw new MuseGapFillError("pageFailed",after,target2,new MuseForeignSessionError(`view/page for ${this.#options.sessionId} served an event for session ${named2}`))}#drain(paged){let buffered=this.#buffer.splice(0);if(this.#filling=!1,this.#options.discarded())return NO_RETIREMENTS;let sink={retirements:[],tasks:[]},served=new Set;for(let frame of paged){
|
|
8049
8053
|
let cursor3=_a3.#viewCursorOf(frame);cursor3!==void 0&&served.add(cursor3),this.#options.apply(frame,sink)}for(let frame of buffered){let cursor3=_a3.#viewCursorOf(frame);if(cursor3!==void 0&&(served.has(cursor3)||this.#servedTwins.has(cursor3))){this.#servedTwins.delete(cursor3);continue}this.#options.apply(frame,sink)}return sink.tasks.length===0?Promise.resolve(sink.retirements):Promise.all(sink.tasks).then(batches=>[...sink.retirements,...batches.flat()])}static#viewCursorOf(frame){let cursor3=frame.
|
|
8050
|
-
params?.viewCursor;return typeof cursor3=="string"?cursor3:void 0}#reportFailure(error62){if(error62 instanceof MuseGapFillError){this.#report(error62);return}let gap=this.#options.fold.pendingGap;this.#report(new MuseGapFillError("pageFailed",gap?.after??"",gap?.next??"",error62))}#report(failure2){try{this.#onFailure?.(failure2)}catch{}}};_a3=GapFiller}});var init_turn_handle=__esm({"node_modules/.pnpm/@muse-code+sdk@1.4.6_@types+node@26.2.0/node_modules/@muse-code/sdk/dist/src/facade/turn-handle.js"(){}});var NO_IO,init_session=__esm({"node_modules/.pnpm/@muse-code+sdk@1.4.6_@types+node@26.2.0/node_modules/@muse-code/sdk/dist/src/facade/session.js"(){init_session_fold();init_pending_command_set();init_approval();init_turn_submit();init_gap_fill();init_host_death();init_errors6();init_turn_handle();NO_IO=Promise.resolve([])}});var init_client=__esm({"node_modules/.pnpm/@muse-code+sdk@1.4.6_@types+node@26.2.0/node_modules/@muse-code/sdk/dist/src/facade/client.js"(){init_spawn();init_errors6();init_discarded();init_host_death();init_connection3();init_host_start();init_session()}});var init_src=__esm({"node_modules/.pnpm/@muse-code+sdk@1.4.6_@types+node@26.2.0/node_modules/@muse-code/sdk/dist/src/index.js"(){init_fingerprint();init_item_store();init_state_store();init_session_fold();init_pending_command_set();init_connection3();init_spawn();init_client();init_discarded();init_errors6();init_host_death();init_host_start();init_session();init_turn_handle()}});import{existsSync as
|
|
8054
|
+
params?.viewCursor;return typeof cursor3=="string"?cursor3:void 0}#reportFailure(error62){if(error62 instanceof MuseGapFillError){this.#report(error62);return}let gap=this.#options.fold.pendingGap;this.#report(new MuseGapFillError("pageFailed",gap?.after??"",gap?.next??"",error62))}#report(failure2){try{this.#onFailure?.(failure2)}catch{}}};_a3=GapFiller}});var init_turn_handle=__esm({"node_modules/.pnpm/@muse-code+sdk@1.4.6_@types+node@26.2.0/node_modules/@muse-code/sdk/dist/src/facade/turn-handle.js"(){}});var NO_IO,init_session=__esm({"node_modules/.pnpm/@muse-code+sdk@1.4.6_@types+node@26.2.0/node_modules/@muse-code/sdk/dist/src/facade/session.js"(){init_session_fold();init_pending_command_set();init_approval();init_turn_submit();init_gap_fill();init_host_death();init_errors6();init_turn_handle();NO_IO=Promise.resolve([])}});var init_client=__esm({"node_modules/.pnpm/@muse-code+sdk@1.4.6_@types+node@26.2.0/node_modules/@muse-code/sdk/dist/src/facade/client.js"(){init_spawn();init_errors6();init_discarded();init_host_death();init_connection3();init_host_start();init_session()}});var init_src=__esm({"node_modules/.pnpm/@muse-code+sdk@1.4.6_@types+node@26.2.0/node_modules/@muse-code/sdk/dist/src/index.js"(){init_fingerprint();init_item_store();init_state_store();init_session_fold();init_pending_command_set();init_connection3();init_spawn();init_client();init_discarded();init_errors6();init_host_death();init_host_start();init_session();init_turn_handle()}});import{existsSync as existsSync39,mkdtempSync as mkdtempSync12,rmSync as rmSync28}from"node:fs";import{readFile as readFile8}from"node:fs/promises";import{homedir as homedir30,tmpdir as tmpdir17}from"node:os";import{join as join99}from"node:path";function museModelLabel(id,displayLabel){return displayLabel&&displayLabel!==id?displayLabel:/^muse-/i.test(id)?id.split("-").map(word=>/^\d/.test(word)?word:word.charAt(0).toUpperCase()+word.slice(1)).join(" "):id}function museCatalog(result2,preferred){
|
|
8051
8055
|
let rows=result2?.models;if(!Array.isArray(rows))return null;let options2=[],listedDefault;for(let row of rows){let entry=row??{};if(typeof entry.modelId!="string"||!entry.modelId.trim()||options2.some(option=>option.id===entry.modelId))continue;let id=entry.modelId;options2.push({id,label:museModelLabel(id,typeof entry.displayLabel=="string"?entry.displayLabel:void 0),contextWindow:typeof entry.contextLimit=="number"&&entry.contextLimit>0?entry.contextLimit:MUSE_CONTEXT_WINDOW2}),entry.isDefault===
|
|
8052
8056
|
!0&&(listedDefault??=id)}return options2.length?(preferred&&!options2.some(option=>option.id===preferred)&&options2.unshift({id:preferred,label:museModelLabel(preferred),custom:!0}),{default:preferred??listedDefault??options2[0].id,options:options2}):null}function museApprovalMode(mode){return mode==="full"?"allowAll":"promptUnmatched"}function museServeArgs(mode){return["serve","--trust-workspace",...mode==="full"?["--disable-sandbox"]:[]]}function museChoice(choices,behavior,always=!1){if(behavior===
|
|
8053
8057
|
"allow"){let once=choices.find(choice=>choice.decision==="approved"),session=choices.find(choice=>choice.decision==="approvedForSession")??choices.find(choice=>choice.decision==="approvedPolicyAmendment"&&choice.scope==="session");return always?session??once:once??session}return choices.find(choice=>choice.decision==="denied")??choices.find(choice=>choice.decision==="abort")}function parseArgs2(args){if(args)try{let parsed=JSON.parse(args);return parsed&&typeof parsed=="object"&&!Array.isArray(parsed)?
|
|
@@ -8064,9 +8068,9 @@ listeners2=new Set,threads=new Map,catalog=config3.model?museCatalog({models:DEF
|
|
|
8064
8068
|
...PROVIDER_CREDENTIAL_ENV,...WORKSPACE_CREDENTIAL_ENV])delete env[key2];return stripControlPlaneEnv(env),input2.environment.META_API_KEY&&(env.META_API_KEY=input2.environment.META_API_KEY),env},launch=args=>process.platform==="win32"?{command:process.env.ComSpec??"cmd.exe",args:["/d","/c",config3.cli,...args]}:{command:config3.cli,args},startHost=async(args,cwd,key2,requestMcp,owner)=>{let{command,args:argv}=launch(args),env=childEnv(),child=spawnCli(command,argv,{cwd,env,stdio:["pipe","pipe","\
|
|
8065
8069
|
pipe"],box:{allowEnv:instanceEnvNames(input2.environment,env)}},owner),spawnError;child.once("error",error62=>{spawnError=error62});let exited=new Promise(resolve35=>child.once("close",()=>resolve35())),connection=new Connection(stdioTransport(child,exited)),timer2;try{let initialized=await Promise.race([connection.request("initialize",{clientInfo:CLIENT_INFO,capabilities:{requestedCapabilities:requestMcp?["sessionMcp"]:[]}}),new Promise((_resolve,reject)=>{timer2=setTimeout(()=>reject(new Error(
|
|
8066
8070
|
"Muse Code did not start within 30 seconds.")),STARTUP_TIMEOUT_MS2),timer2.unref?.()})]);connection.notify("initialized"),await connection.flush();let granted=initialized.grantedCapabilities,host2={connection,exited,key:key2,closed:!1,grantedMcp:Array.isArray(granted)&&granted.includes("sessionMcp"),close:()=>(host2.closed=!0,connection.close())};return connection.onServerRequest(async request2=>{if(request2.method==="approval/request"||request2.method==="userInput/request")return{};throw new Error(
|
|
8067
|
-
`Unsupported Muse request: ${request2.method}`)}),host2}catch(error62){throw await connection.close().catch(()=>{}),spawnError?new Error(describeSpawnFailure(spawnError,config3.cli,cwd).message):error62}finally{timer2&&clearTimeout(timer2)}},refreshModels=async()=>{let cwd=mkdtempSync12(
|
|
8071
|
+
`Unsupported Muse request: ${request2.method}`)}),host2}catch(error62){throw await connection.close().catch(()=>{}),spawnError?new Error(describeSpawnFailure(spawnError,config3.cli,cwd).message):error62}finally{timer2&&clearTimeout(timer2)}},refreshModels=async()=>{let cwd=mkdtempSync12(join99(tmpdir17(),"omb-muse-models-")),host2;try{host2=await startHost(["serve","--disable-shell","--disable-write","--no-session-log"],cwd,"models",!1,"openmausbot");let result2=await Promise.race([host2.connection.
|
|
8068
8072
|
request("model/list",{}),new Promise((_resolve,reject)=>setTimeout(()=>reject(new Error("Muse Code did not list its models.")),MODEL_LIST_TIMEOUT_MS).unref?.())]),listed2=museCatalog(result2,config3.model);listed2&&(catalog=listed2,catalogLoaded=!0,catalogError=null)}catch(error62){catalogError=error62 instanceof Error?error62.message:String(error62)}finally{await host2?.close().catch(()=>{}),rmSync28(cwd,{recursive:!0,force:!0})}},signedIn=()=>{if(input2.environment.META_API_KEY)return!0;let env=childEnv(),
|
|
8069
|
-
home2=env.HOME||
|
|
8073
|
+
home2=env.HOME||homedir30();return existsSync39(join99(env.XDG_CONFIG_HOME||join99(home2,".config"),"muse","auth.json"))||existsSync39(join99(home2,".config","muse","auth.json"))},version2,probeVersion2=()=>new Promise(resolve35=>{execCli(config3.cli,["--version"],{env:childEnv(),timeout:15e3},(error62,stdout2)=>{resolve35(error62?null:(/(\d+\.\d+\.\d+[\w.-]*)/.exec(stdout2)?.[1]??stdout2.trim())||null)})}),threadOf=threadId=>{let state=threads.get(threadId);return state||threads.set(threadId,state=
|
|
8070
8074
|
{threadId,pending:new Map}),state},finishTurn=(state,active,completed)=>{if(!active.finished){active.finished=!0,active.onFinished?.(),state.active===active&&(state.active=void 0);for(let requestId of state.pending.keys())emit({type:"request.resolved",threadId:state.threadId,turnId:active.turnId,requestId,behavior:"deny",source:"system"});state.pending.clear(),completed.ok&&active.receipt&&writePromptSplitReceipt(DRIVER_KIND6,active.receipt.key,active.receipt.receipt),emit({type:"turn.completed",
|
|
8071
8075
|
threadId:state.threadId,turnId:active.turnId,ok:completed.ok,...completed.stopReason?{stopReason:completed.stopReason}:{},...completed.usage?{usage:completed.usage}:{}})}},failTurn=(state,active,message5)=>{active.finished||(emit({type:"runtime.error",threadId:state.threadId,turnId:active.turnId,message:redactSecretsInText(message5),terminal:!0}),finishTurn(state,active,{ok:!1,stopReason:"error"}))},onNotification=(state,host2,method,params)=>{if(state.host!==host2||params.sessionId!==state.sessionId)
|
|
8072
8076
|
return;let active=state.active,threadId=state.threadId;switch(method){case"item/started":case"item/updated":case"item/completed":{let item=params.item;if(!active||!item||item.turnId!==active.nativeTurnId)return;let seen=active.items.get(item.itemId);if(active.items.set(item.itemId,item),item.kind==="agentMessage"){if(item.status!=="completed"||item.retracted)return;let text13=item.text??"",streamed=active.streamed.get(item.itemId)??"";text13.startsWith(streamed)&&text13.length>streamed.length&&emit(
|
|
@@ -8100,7 +8104,7 @@ let answer=byId[id];if(answer===void 0)return[];let labels=question.options.map(
|
|
|
8100
8104
|
answers}),emit({type:"request.resolved",threadId,...turnId?{turnId}:{},requestId,behavior:"answer",source:"user"}),"answered"}catch{return"unavailable"}},async steer(threadId,text13){let state=threads.get(threadId),active=state?.active;if(!state?.host||!state.sessionId||!active?.nativeTurnId||active.finished)return"refused";try{return await state.host.connection.command("turn/steer",{sessionId:state.sessionId,expectedTurnId:active.nativeTurnId,input:[{type:"text",text:text13}]}),"steered"}catch(error62){
|
|
8101
8105
|
return error62 instanceof MspError?"refused":"indeterminate"}},hasSession:threadId=>!!threads.get(threadId)?.sessionId,async stopAll(){await Promise.all([...threads.values()].map(async state=>{state.active&&await(state.active.stopping??=endUnconfirmed(state,state.active)),await closeHost(state)}))},onEvent(listener){return listeners2.add(listener),()=>listeners2.delete(listener)}};return refreshModels(),{instanceId,driverKind:DRIVER_KIND6,displayName:input2.displayName,enabled:input2.enabled,get models(){
|
|
8102
8106
|
return catalog},refreshModels,adapter,async snapshot(){return version2??=await probeVersion2(),version2===null?(version2=void 0,{state:"unavailable",reason:"Muse Code isn't installed on this computer.",authenticated:!1}):signedIn()?{state:"available",authenticated:!0,version:version2,billing:input2.environment.META_API_KEY?"metered":"subscription",...!catalogLoaded&&catalogError?{warning:{title:"Muse Code models",message:"Muse Code did not list its models yet; showing the known ones."}}:{},account:{
|
|
8103
|
-
method:input2.environment.META_API_KEY?"api-key":"login"}}:{state:"unavailable",reason:"Sign in to Muse Code: run `muse login` in a terminal.",authenticated:!1,version:version2}},async dispose(){await adapter.stopAll(),threads.clear(),listeners2.clear()}}}}}});import{readFileSync as
|
|
8107
|
+
method:input2.environment.META_API_KEY?"api-key":"login"}}:{state:"unavailable",reason:"Sign in to Muse Code: run `muse login` in a terminal.",authenticated:!1,version:version2}},async dispose(){await adapter.stopAll(),threads.clear(),listeners2.clear()}}}}}});import{readFileSync as readFileSync57}from"node:fs";import{homedir as homedir31}from"node:os";import{join as join100}from"node:path";function normalizedApiUrl(value){let root=value.trim().replace(/\/+$/,"");return root.endsWith("/v1")?root:`${root}/v1`}function loadLocalMiniMaxConfig(home2=homedir31()){try{let raw=localConfigSchema.parse(JSON.parse(readFileSync57(join100(home2,".mmx","config.json"),"utf8"))),configuredUrl2=raw.base_url?.trim()?raw.base_url:raw.region==="cn"?CN_URL:DEFAULT_URL8;return{
|
|
8104
8108
|
apiKey:raw.api_key?.trim()??"",url:normalizedApiUrl(configuredUrl2),defaultModel:raw.default_text_model?.trim()??""}}catch{return{apiKey:"",url:DEFAULT_URL8,defaultModel:""}}}function decodeMinimaxConfig(raw){let tools=(raw??{}).tools;if(tools!==void 0&&typeof tools!="boolean")throw new Error("tools must be a boolean");let parsed=driverConfigSchema.safeParse(raw??{}),url3=(parsed.success?parsed.data:{}).url?.trim()||process.env.MINIMAX_BASE_URL?.trim();return{...tools!==void 0?{tools}:{},...url3?
|
|
8105
8109
|
{url:normalizedApiUrl(url3)}:{}}}var DRIVER_KIND7,API_KEY_ENV3,DEFAULT_URL8,CN_URL,MODELS7,localConfigSchema,driverConfigSchema,MinimaxDriver,init_minimax=__esm({"server/drivers/minimax.ts"(){"use strict";init_zod();init_openai_chat();DRIVER_KIND7="minimax",API_KEY_ENV3="MINIMAX_API_KEY",DEFAULT_URL8="https://api.minimax.io/v1",CN_URL="https://api.minimaxi.com/v1",MODELS7={default:"MiniMax-M3",options:[{id:"MiniMax-M3",label:"MiniMax M3",contextWindow:1e6,custom:!0},{id:"MiniMax-M2.7",label:"Min\
|
|
8106
8110
|
iMax M2.7",contextWindow:204800,custom:!0},{id:"MiniMax-M2.7-highspeed",label:"MiniMax M2.7 Highspeed",contextWindow:204800,custom:!0}]},localConfigSchema=external_exports.object({api_key:external_exports.string().optional(),region:external_exports.enum(["global","cn"]).optional(),base_url:external_exports.string().optional(),default_text_model:external_exports.string().optional()}),driverConfigSchema=external_exports.object({url:external_exports.string().optional()});MinimaxDriver={driverKind:DRIVER_KIND7,
|
|
@@ -8118,10 +8122,10 @@ key2)),models2=new Map;for(let entry of Array.isArray(json3?.data)?json3.data:[]
|
|
|
8118
8122
|
ider manually.");return[...models2.values()]}async function verifySetupCompletion(url3,key2,model,provider){let id=model.trim();if(!id||/[\u0000-\u001f\u007f]/u.test(id))throw new SetupApiError("Choose a non-empty model ID without control characters.");let host2=new URL(normalizeApiUrl(url3)).hostname.toLowerCase(),pinProvider=provider&&(host2==="openrouter.ai"||host2.endsWith(".openrouter.ai")),json3=record11(await setupJson(url3,key2,{model:id,messages:[{role:"user",content:"Reply with exactly\
|
|
8119
8123
|
OK."}],stream:!1,...pinProvider?{provider:{order:[provider],allow_fallbacks:!1}}:{}})),choice=record11(Array.isArray(json3?.choices)?json3.choices[0]:void 0),message5=record11(choice?.message);if(message5?.role!=="assistant"||typeof message5.content!="string"||!message5.content.trim())throw new SetupApiError("The API did not return an assistant text reply. Choose a model that supports Chat Completions, then try again.")}var API_ENDPOINTS,SetupApiError,record11,init_cli_api_setup=__esm({"server/\
|
|
8120
8124
|
cli-api-setup.ts"(){"use strict";API_ENDPOINTS=[{id:"openai",label:"OpenAI API",url:"https://api.openai.com/v1",keyUrl:"https://platform.openai.com/api-keys"},{id:"openrouter",label:"OpenRouter",url:"https://openrouter.ai/api/v1",keyUrl:"https://openrouter.ai/settings/keys"},{id:"groq",label:"Groq",url:"https://api.groq.com/openai/v1",keyUrl:"https://console.groq.com/keys"},{id:"meta",label:"Meta Model API",url:"https://api.meta.ai/v1",keyUrl:"https://dev.meta.ai/"}];SetupApiError=class extends Error{};
|
|
8121
|
-
record11=value=>value!==null&&typeof value=="object"&&!Array.isArray(value)?value:void 0}});var cli_setup_exports={};__export(cli_setup_exports,{isSetupComplete:()=>isSetupComplete,readCliStartup:()=>readCliStartup,runSetup:()=>runSetup,runSetupCli:()=>runSetupCli,saveCliStartup:()=>saveCliStartup});import{spawn as spawn10}from"node:child_process";import{readFileSync as
|
|
8125
|
+
record11=value=>value!==null&&typeof value=="object"&&!Array.isArray(value)?value:void 0}});var cli_setup_exports={};__export(cli_setup_exports,{isSetupComplete:()=>isSetupComplete,readCliStartup:()=>readCliStartup,runSetup:()=>runSetup,runSetupCli:()=>runSetupCli,saveCliStartup:()=>saveCliStartup});import{spawn as spawn10}from"node:child_process";import{readFileSync as readFileSync58}from"node:fs";import{join as join101,resolve as resolve29}from"node:path";import{randomUUID as randomUUID17}from"node:crypto";async function inspect(id,entry){let registry2=new ProviderRegistry(BUILT_IN_DRIVERS);
|
|
8122
8126
|
try{await registry2.load({[id]:entry});let provider=registry2.get(id);if(!provider)throw new Error("This provider configuration could not be loaded. Check it in app Settings.");return{snapshot:await provider.snapshot(),models:provider.models}}finally{await registry2.disposeAll()}}async function runSetupCli(cli,args,environment={}){let env={...process.env,...environment,PATH:augmentedPath()};stripWorkspaceCredentialEnv(env);for(let key2 of PROVIDER_CREDENTIAL_ENV)delete env[key2];delete env.CLAUDECODE,
|
|
8123
8127
|
delete env.CLAUDE_CODE_ENTRYPOINT;let command=resolveCli(cli,args);await new Promise((done,reject)=>{let child=spawn10(command.command,command.args,{env,stdio:"inherit"});child.once("error",()=>reject(new Error(`Could not start ${cli}. Check that it is installed and on PATH.`))),child.once("exit",(code,signal)=>{code===0?done():reject(signal==="SIGINT"||code===130?new SetupCancelled:new Error(`${cli} did not finish successfully. Fix the error shown above, then try again.`))})}),resetPathCache()}
|
|
8124
|
-
function assertDataDir(dataDir){if(resolve29(dataDir)!==resolve29(DATA_DIR))throw new Error("Setup data directory mismatch. Restart the CLI with --data-dir.")}function checkStoredConfig(dataDir){try{parseStoredConfig(JSON.parse(
|
|
8128
|
+
function assertDataDir(dataDir){if(resolve29(dataDir)!==resolve29(DATA_DIR))throw new Error("Setup data directory mismatch. Restart the CLI with --data-dir.")}function checkStoredConfig(dataDir){try{parseStoredConfig(JSON.parse(readFileSync58(join101(dataDir,"config.json"),"utf8")))}catch(error62){if(error62.code==="ENOENT")return;throw new Error("Existing config.json could not be read or validated. Setup has not changed it; repair it before continuing.")}}async function isSetupComplete(dataDir){
|
|
8125
8129
|
assertDataDir(dataDir),checkStoredConfig(dataDir);let cfg=loadConfig(),saved=cfg.defaultModelSelection,instances=instanceConfigs(cfg);return!!(saved&&Object.hasOwn(instances,saved.instanceId)&&instances[saved.instanceId]?.enabled!==!1)}function readCliStartup(dataDir){return assertDataDir(dataDir),checkStoredConfig(dataDir),loadConfig().cliStartup}function saveCliStartup(dataDir,settings2){assertDataDir(dataDir);let lease=acquireDataDirLease(dataDir);try{checkStoredConfig(dataDir),saveConfig({cliStartup:settings2})}finally{
|
|
8126
8130
|
lease.release()}}function rawObject(value){return value&&typeof value=="object"&&!Array.isArray(value)?value:{}}async function chooseModel(io2,models2){if(!models2.options.length)throw new Error("This connection returned no models. Check the provider and try again.");let query2="";for(;;){let matches2=models2.options.filter(m3=>`${m3.label} ${m3.id}`.toLowerCase().includes(query2.toLowerCase())),preferred=matches2.find(m3=>m3.id===models2.default),visible=(preferred?[preferred,...matches2.filter(
|
|
8127
8131
|
m3=>m3!==preferred)]:matches2).slice(0,20),defaultIndex=visible.findIndex(m3=>m3.id===models2.default),selected=await io2.choose("Choose your model",[...visible.map(m3=>m3.label.trim()||m3.id),"Search models\u2026"],defaultIndex<0?void 0:defaultIndex);if(selected<visible.length)return visible[selected].id;query2=(await io2.ask("Model name or part of its ID (Enter shows all): ")).trim()}}async function connectNative(choice,id,entry,io2,deps){let cli=typeof rawObject(entry.config).cli=="string"?rawObject(
|
|
@@ -8245,7 +8249,7 @@ type:"string",description:"Optional owned task/thread ID. Omit to change the bot
|
|
|
8245
8249
|
message, which forks the conversation from that point and answers again. This is the rewind a person performs in the composer, and the only mapped way to make the harness rebuild a thread's context instead of resuming the provider's own session. Refused while the thread is working.",inputSchema:{type:"object",properties:{bot_id:{type:"string",description:"The ID of the bot."},message_id:{type:"string",description:"The user message to replace."},text:{type:"string",description:"What that message \
|
|
8246
8250
|
should say instead."},task_id:{type:"string",description:"Optional owned task/thread ID. Defaults to the bot's selected task."}},required:["bot_id","message_id","text"],additionalProperties:!1},annotations:MUTATING},{name:"list_available_models",description:"List configured model instances and capabilities without exposing local executable paths.",inputSchema:{type:"object",properties:{},additionalProperties:!1},annotations:READ_ONLY},{name:"interrupt_conversation",description:"Interrupt one bot\
|
|
8247
8251
|
or channel task's turn without stopping other bot tasks.",inputSchema:{type:"object",properties:{target_type:{type:"string",enum:["bot","channel"]},target_id:{type:"string"},task_id:{type:"string",description:"Optional task/thread ID. Defaults to the selected task."}},required:["target_type","target_id"],additionalProperties:!1},annotations:DESTRUCTIVE}];ToolInputError=class extends Error{};FINAL_JOB_STATES=new Set(["needs-input","completed","failed","stalled","idle"]);activeMcpRequests=new Map,
|
|
8248
|
-
activeMcpControllers=new Set;process.argv[1]&&(process.argv[1].endsWith("mcp-server.ts")||process.argv[1].endsWith("mcp-server.js"))&&runStdio()}});import{readFileSync as
|
|
8252
|
+
activeMcpControllers=new Set;process.argv[1]&&(process.argv[1].endsWith("mcp-server.ts")||process.argv[1].endsWith("mcp-server.js"))&&runStdio()}});import{readFileSync as readFileSync59}from"node:fs";async function loadMcp(){mcpModule??=Promise.resolve().then(()=>(init_mcp_server(),mcp_server_exports));try{return await mcpModule}catch(error62){throw mcpModule=void 0,usageError(`OPENMAUSBOT_URL is not usable: ${error62 instanceof Error?error62.message:String(error62)}`)}}function readToken(flags,env){let file2=flag(flags,"token-file");if(file2!==void 0){let token;try{token=readFileSync59(file2,"utf8").trim()}catch(error62){throw usageError(`\
|
|
8249
8253
|
--token-file ${file2} could not be read (${error62.code??"error"})`)}if(!token)throw usageError(`--token-file ${file2} is empty`);return token}return env.OPENMAUSBOT_TOKEN?.trim()||void 0}function namedServer(flags,env){let url3=flag(flags,"url")?.trim();if(url3)return{url:url3};let port=flag(flags,"port")?.trim();return port?{port}:env.OPENMAUSBOT_URL?.trim()?{url:env.OPENMAUSBOT_URL.trim()}:env.OMB_PORT?.trim()?{port:env.OMB_PORT.trim()}:void 0}async function openClient(flags,deps,mutating){let mcp=await loadMcp(),
|
|
8250
8254
|
token=readToken(flags,deps.env),named2=namedServer(flags,deps.env),baseUrl;if(named2&&"url"in named2)try{baseUrl=mcp.validateBaseUrl(named2.url)}catch(error62){throw usageError(error62 instanceof Error?error62.message:String(error62))}else if(named2){let port=Number(named2.port);if(!Number.isInteger(port)||port<1||port>65535)throw usageError("--port must be 1-65535");baseUrl=`http://127.0.0.1:${port}`}else{if(mutating&&deps.requireExplicitForMutations)throw usageError("mutating commands require \
|
|
8251
8255
|
an explicit Limix Bot instance","start `control-omb launch`, then pass its URL with --url");if(token)throw usageError("a token needs a named server, so it is never sent while looking for one","pass --url (or --port), or set OPENMAUSBOT_URL or OMB_PORT");try{baseUrl=await mcp.probeBaseUrls(DISCOVERY_PORTS.map(port=>`http://127.0.0.1:${port}`))}catch{throw new HeadlessError(`no Limix Bot server answered on 127.0.0.1 ports ${DISCOVERY_PORTS.join(", ")}`,EXIT.unreachable,"start one with `limixbot se\
|
|
@@ -8255,40 +8259,40 @@ return message5}}async function explain(error62,baseUrl){if(error62 instanceof H
|
|
|
8255
8259
|
with `limixbot connect URL --out FILE`, then pass --token-file FILE or set OPENMAUSBOT_TOKEN");if(status2===403)return new HeadlessError(`not allowed: ${message5}`,EXIT.unreachable,"this needs a paired session with the right scope: `limixbot connect` mints one on this computer");if(status2===404&&/^no such (bot|channel|conversation|task|message)\b/i.test(message5))return usageError(message5,"openmausbot bots and openmausbot channels list the ids");if(/cannot report a conversation's job/.test(message5))
|
|
8256
8260
|
return new HeadlessError(message5,EXIT.unreachable,"update Limix Bot on the server");let cause=error62?.cause?.code;return error62 instanceof TypeError&&/fetch failed/i.test(message5)||cause==="ECONNREFUSED"||cause==="ENOTFOUND"||error62 instanceof Error&&(error62.name==="TimeoutError"||/timed out|aborted due to timeout/i.test(message5))?new HeadlessError(`cannot reach Limix Bot${baseUrl?` at ${baseUrl}`:""}`,EXIT.unreachable,"check the server is running and the address is right (limixbot doctor\
|
|
8257
8261
|
)"):error62 instanceof Error&&error62.name==="AbortError"?new HeadlessError("stopped",EXIT.interrupted):new HeadlessError(message5,EXIT.failed)}async function readJob(client,threadId,query2={}){try{return await client.json(`/api/threads/${encodeURIComponent(threadId)}/job?${new URLSearchParams(query2).toString()}`)}catch(error62){let status2=error62.status,message5=error62 instanceof Error?error62.message:String(error62);throw status2===404&&!/no such conversation/.test(message5)?new HeadlessError(
|
|
8258
|
-
"this Limix Bot server cannot report a conversation's job",EXIT.unreachable,"update Limix Bot on the server"):error62}}var DISCOVERY_PORTS,mcpModule,init_client2=__esm({"server/headless/client.ts"(){"use strict";init_args();DISCOVERY_PORTS=[8799,18799,28799]}});import{randomBytes as randomBytes10}from"node:crypto";import{readFileSync as
|
|
8262
|
+
"this Limix Bot server cannot report a conversation's job",EXIT.unreachable,"update Limix Bot on the server"):error62}}var DISCOVERY_PORTS,mcpModule,init_client2=__esm({"server/headless/client.ts"(){"use strict";init_args();DISCOVERY_PORTS=[8799,18799,28799]}});import{randomBytes as randomBytes10}from"node:crypto";import{readFileSync as readFileSync60}from"node:fs";async function resolveTarget2(ctx,positional,allow="any"){let bot=flag(ctx.flags,"bot")?.trim(),channel=flag(ctx.flags,"channel")?.trim(),thread=flag(ctx.flags,"thread")?.trim(),named2=[bot,channel,thread,positional?.trim()].filter(Boolean),what=allow==="bot"?"a bot":allow==="channel"?"a room":"a bot or room";if(named2.length!==1)throw usageError(named2.length?`name exactly one ${what.slice(
|
|
8259
8263
|
2)}`:`${what} is required`,`openmausbot ${ctx.verb} NAME, or --bot ID${allow==="bot"?"":", --channel ID"} or --thread ID`);let task=flag(ctx.flags,"task")?.trim(),withTask=target2=>{if(allow!=="any"&&target2.type!==allow)throw usageError(`${ctx.verb} needs ${what}; that is ${target2.type==="bot"?"a bot":"a room"}`);return task&&!target2.taskId?{...target2,taskId:task}:target2};if(bot)return withTask({type:"bot",id:bot});if(channel)return withTask({type:"channel",id:channel});let fleet2=await(await ctx.
|
|
8260
8264
|
client()).json("/api/bots?messages=0"),bots=fleet2.bots??[],rooms=(fleet2.groups??[]).filter(group=>!group.dm);if(thread){let owner=bots.find(candidate=>owns(candidate,thread)),room=owner?void 0:rooms.find(candidate=>owns(candidate,thread));if(!owner&&!room)throw usageError(`no conversation with id ${thread}`,"run openmausbot bots or openmausbot channels");return withTask(owner?{type:"bot",id:owner.id,name:owner.name,taskId:thread}:{type:"channel",id:room.id,name:room.name,taskId:thread})}let wanted=positional.
|
|
8261
8265
|
trim(),byId=bots.find(candidate=>candidate.id===wanted)??rooms.find(candidate=>candidate.id===wanted);if(byId)return withTask({type:bots.includes(byId)?"bot":"channel",id:byId.id,name:byId.name});let key2=wanted.toLowerCase(),matches2=[...allow!=="channel"?bots.filter(candidate=>String(candidate.name).trim().toLowerCase()===key2).map(record13=>({record:record13,type:"bot"})):[],...allow!=="bot"?rooms.filter(candidate=>String(candidate.name).trim().toLowerCase()===key2).map(record13=>({record:record13,
|
|
8262
8266
|
type:"channel"})):[]];if(matches2.length===0)throw usageError(`no ${allow==="channel"?"room":allow==="bot"?"bot":"bot or room"} named "${wanted}"`,"run openmausbot bots or openmausbot channels for the names");if(matches2.length>1)throw usageError(`"${wanted}" names ${matches2.length} ${allow==="any"?"bots or rooms":`${what.slice(2)}s`}: ${matches2.map(({record:record13,type:type3})=>`${record13.name} (${type3==="bot"?"bot":"room"}, id ${record13.id})`).join("; ")}`,"use --bot ID or --channel ID");
|
|
8263
8267
|
let[{record:record12,type:type2}]=matches2;return withTask({type:type2,id:record12.id,name:record12.name})}async function conversationFor(client,target2,task,title="Headless run"){if(task==="new")return(await client.tool("create_task",{target_type:target2.type,target_id:target2.id,title})).task.taskId;if(task!=="current")return task;let fleet2=await client.json("/api/bots?messages=0"),owner=(target2.type==="bot"?fleet2.bots:fleet2.groups)?.find(record12=>record12.id===target2.id);if(!owner)throw usageError(
|
|
8264
8268
|
`no ${target2.type==="bot"?"bot":"room"} with id ${target2.id}`);return owner.threadId}async function readMessage(ctx,positional){let text13=flag(ctx.flags,"text"),file2=flag(ctx.flags,"message-file"),sources=[positional!==void 0,text13!==void 0,file2!==void 0].filter(Boolean).length;if(sources!==1)throw usageError(sources?"give the message one way: TEXT, --text TEXT, --message-file FILE or -":"a message is required",`openmausbot ${ctx.verb} TARGET "what to do", or --message-file FILE, or - to r\
|
|
8265
|
-
ead it from stdin`);let message5;if(file2!==void 0)try{message5=
|
|
8269
|
+
ead it from stdin`);let message5;if(file2!==void 0)try{message5=readFileSync60(file2,"utf8")}catch(error62){throw usageError(`--message-file ${file2} could not be read (${error62.code??"error"})`)}else positional==="-"?message5=await ctx.io.readStdin():message5=text13??positional;if(!message5.trim())throw usageError("the message is empty");return message5.trim()}var owns,conversationTitle,newSendId,waitPolicy,init_context=__esm({"server/headless/context.ts"(){"use strict";init_args();owns=(record12,threadId)=>record12.
|
|
8266
8270
|
threadId===threadId||Array.isArray(record12.tasks)&&record12.tasks.some(task=>task.threadId===threadId);conversationTitle=(ctx,text13)=>(flag(ctx.flags,"title")??text13.split(`
|
|
8267
8271
|
`)[0]).trim().slice(0,80)||"Headless run";newSendId=()=>`cli-${randomBytes10(12).toString("base64url")}`,waitPolicy=ctx=>({onInput:oneOf(flag(ctx.flags,"on-input"),"--on-input",["exit","wait","stop"],"exit"),onTimeout:oneOf(flag(ctx.flags,"on-timeout"),"--on-timeout",["leave","stop"],"leave"),strict:ctx.flags.strict===!0,timeoutMs:flag(ctx.flags,"timeout")?parseDuration(flag(ctx.flags,"timeout"),"--timeout"):ctx.defaultWaitMs})}});function processIo(){return{out:text13=>{process.stdout.write(`${text13}
|
|
8268
8272
|
`)},err:text13=>{process.stderr.write(`${text13}
|
|
8269
8273
|
`)},readStdin:async()=>{let chunks=[];for await(let chunk of process.stdin)chunks.push(Buffer.isBuffer(chunk)?chunk:Buffer.from(String(chunk)));return Buffer.concat(chunks).toString("utf8")}}}function redactDeep(value){return typeof value=="string"?redactSecretsInText(value):Array.isArray(value)?value.map(redactDeep):value&&typeof value=="object"?Object.fromEntries(Object.entries(value).map(([key2,entry])=>[key2,redactDeep(entry)])):value}var Output,shortId,oneLine2,init_output=__esm({"server/he\
|
|
8270
8274
|
adless/output.ts"(){"use strict";init_redact();Output=class{json;quiet;io;constructor(io2,mode){this.io=io2,this.json=mode.json===!0,this.quiet=mode.quiet===!0}progress(event){this.quiet||this.io.err(JSON.stringify(redactDeep(event)))}result(value,human){if(this.json)this.io.out(JSON.stringify(redactDeep(value),null,2));else for(let line3 of human)this.io.out(redactSecretsInText(line3))}error(error62){let body={ok:!1,error:error62.message,...error62.hint?{hint:error62.hint}:{},exitCode:error62.exitCode};
|
|
8271
|
-
this.json?this.io.out(JSON.stringify(redactDeep(body),null,2)):(this.io.err(redactSecretsInText(`error: ${error62.message}`)),error62.hint&&this.io.err(redactSecretsInText(`hint: ${error62.hint}`)))}},shortId=id=>id.length>12?`${id.slice(0,8)}\u2026`:id,oneLine2=(text13,max=120)=>{let flat=text13.replace(/\s+/g," ").trim();return flat.length>max?`${flat.slice(0,max-1)}\u2026`:flat}}});import{createWriteStream as createWriteStream3,existsSync as
|
|
8275
|
+
this.json?this.io.out(JSON.stringify(redactDeep(body),null,2)):(this.io.err(redactSecretsInText(`error: ${error62.message}`)),error62.hint&&this.io.err(redactSecretsInText(`hint: ${error62.hint}`)))}},shortId=id=>id.length>12?`${id.slice(0,8)}\u2026`:id,oneLine2=(text13,max=120)=>{let flat=text13.replace(/\s+/g," ").trim();return flat.length>max?`${flat.slice(0,max-1)}\u2026`:flat}}});import{createWriteStream as createWriteStream3,existsSync as existsSync40,mkdirSync as mkdirSync41,readdirSync as readdirSync19,readFileSync as readFileSync61,rmdirSync,rmSync as rmSync29,writeFileSync as writeFileSync27}from"node:fs";import{basename as basename17,dirname as dirname36,extname as extname4,isAbsolute as isAbsolute20,join as join102,relative as relative10,resolve as resolve30,sep as sep4}from"node:path";import{Readable,Transform as Transform2}from"node:stream";import{pipeline as pipeline3}from"node:stream/promises";
|
|
8272
8276
|
function safeName(raw){let name=basename17(raw.replace(/[\\/]/g,"_")).replace(/[\x00-\x1f<>:"|?*]/g,"_").trim().slice(0,120).replace(/[. ]+$/,"");return name?/^(con|prn|aux|nul|com\d|lpt\d)(\.|$)/i.test(name)?`_${name}`:name:"file"}function fileName(disposition,link2){let star=disposition?.match(/filename\*=UTF-8''([^;]+)/i)?.[1],plain=disposition?.match(/filename="([^"]+)"/i)?.[1],name="";try{name=star?decodeURIComponent(star):plain??decodeURIComponent(basename17(link2.split(/[?#]/)[0]))}catch{
|
|
8273
|
-
name=plain??""}return safeName(name)}function unused(dir,name,taken){let ext=extname4(name),stem2=name.slice(0,name.length-ext.length),candidate=name;for(let n3=2;taken.has(
|
|
8277
|
+
name=plain??""}return safeName(name)}function unused(dir,name,taken){let ext=extname4(name),stem2=name.slice(0,name.length-ext.length),candidate=name;for(let n3=2;taken.has(join102(dir,candidate));n3++)candidate=`${stem2} (${n3})${ext}`;return taken.add(join102(dir,candidate)),candidate}function exportFolder(dir,force){let out=resolve30(dir);if(!existsSync40(out)||force)return out;let entries2;try{entries2=readdirSync19(out)}catch(error62){throw usageError(`${out} cannot be written into (${error62.
|
|
8274
8278
|
code??"error"})`,"choose a folder")}if(entries2.length)throw usageError(`${out} already has files in it`,"choose an empty folder, or pass --force to write into it");return out}function markdownOf(title,messages2,botName){let lines2=[`# ${title}`,""];for(let message5 of messages2){let who=message5.role==="user"?`${message5.sender?.name??"User"}${message5.via==="api"?" (via the local API)":""}`:message5.from?.name??botName;message5.kind==="text"&&message5.text?lines2.push(`**${who}:**`,"",String(message5.
|
|
8275
8279
|
text),""):message5.kind==="activity"&&message5.tool?lines2.push(`> ${message5.tool.name}`,""):message5.kind==="screen"?lines2.push("> [screen capture]",""):message5.kind==="options"&&message5.card&&lines2.push(`> ${message5.card.title}${message5.card.answered?` \u2014 answered: ${message5.card.answered}`:""}`,"")}return lines2.join(`
|
|
8276
|
-
`)}function removeEarlierExport(out){let manifest;try{manifest=JSON.parse(
|
|
8280
|
+
`)}function removeEarlierExport(out){let manifest;try{manifest=JSON.parse(readFileSync61(join102(out,"manifest.json"),"utf8"))}catch{return}let listed2=[manifest.transcripts,manifest.files,manifest.screens].flatMap(entries2=>Array.isArray(entries2)?entries2:[]).map(entry=>entry?.file).filter(file2=>typeof file2=="string"),written=[...listed2,...listed2.filter(file2=>/^transcripts[\\/].*\.json$/.test(file2)).map(file2=>file2.replace(/\.json$/,".md")),"job.json","manifest.json"];for(let file2 of written){
|
|
8277
8281
|
let target2=resolve30(out,file2),inside3=relative10(out,target2);if(!(!inside3||inside3.startsWith("..")||isAbsolute20(inside3))){try{rmSync29(target2,{force:!0})}catch{continue}for(let folder=dirname36(target2);relative10(out,folder)&&!relative10(out,folder).startsWith("..");folder=dirname36(folder))try{rmdirSync(folder)}catch{break}}}}async function writeCapped(response,file2,limit){let written=0,count5=new Transform2({transform(chunk,_encoding,done){written+=chunk.length,written>limit?done(new Error(
|
|
8278
8282
|
"over the byte limit")):done(null,chunk)}}),body=response.body?Readable.fromWeb(response.body):Readable.from([]);try{return await pipeline3(body,count5,createWriteStream3(file2,{mode:384})),written}catch(error62){if(rmSync29(file2,{force:!0}),written>limit)return OVER_LIMIT;throw error62}}async function exportJob(client,options2,output2){let out=exportFolder(options2.out,options2.force===!0);options2.force&&removeEarlierExport(out);let maxFiles=options2.maxFiles??200,maxScreens=options2.maxScreens??
|
|
8279
|
-
100,maxBytes=options2.maxBytes??5e8,job=await readJob(client,options2.threadId,{since:String(options2.since??0),full:"1"}),nodes=(job.nodes??[]).filter(node3=>!options2.root||node3.rootId===options2.root);if(options2.root&&!nodes.length)throw usageError(`no job with root ${options2.root} in this conversation`,"openmausbot export TARGET without --root writes all of it");for(let dir of["transcripts","files","screens"])
|
|
8283
|
+
100,maxBytes=options2.maxBytes??5e8,job=await readJob(client,options2.threadId,{since:String(options2.since??0),full:"1"}),nodes=(job.nodes??[]).filter(node3=>!options2.root||node3.rootId===options2.root);if(options2.root&&!nodes.length)throw usageError(`no job with root ${options2.root} in this conversation`,"openmausbot export TARGET without --root writes all of it");for(let dir of["transcripts","files","screens"])mkdirSync41(join102(out,dir),{recursive:!0});let threads=new Map([[options2.threadId,
|
|
8280
8284
|
"conversation"]]),botNames=new Map;for(let node3 of nodes)threads.has(node3.threadId)||threads.set(node3.threadId,`${node3.botName}${node3.threadTitle?`-${node3.threadTitle}`:""}`),!node3.groupId&&!botNames.has(node3.threadId)&&botNames.set(node3.threadId,String(node3.botName));let transcripts=[],files=[],screens=[],skipped2=[],taken=new Set,bytes2=0,keep=async(response,dir,wanted,about,into)=>{let left=maxBytes-bytes2,declared=Number(response.headers.get("content-length")??Number.NaN);if(Number.
|
|
8281
|
-
isFinite(declared)&&declared>left){await response.body?.cancel(),skipped2.push({...about,reason:`more than --max-bytes ${maxBytes}`});return}
|
|
8285
|
+
isFinite(declared)&&declared>left){await response.body?.cancel(),skipped2.push({...about,reason:`more than --max-bytes ${maxBytes}`});return}mkdirSync41(dir,{recursive:!0});let file2=join102(dir,unused(dir,wanted,taken)),written=await writeCapped(response,file2,left);if(written===OVER_LIMIT){skipped2.push({...about,reason:`more than --max-bytes ${maxBytes}`});return}bytes2+=written,into.push({...about,file:relative10(out,file2).split(sep4).join("/"),bytes:written})},fileRoute=(threadId,messageId,body)=>client.
|
|
8282
8286
|
raw(`/api/threads/${enc(threadId)}/messages/${enc(messageId)}/file`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(body)}).catch(()=>null),saveLinked=async(threadId,folder,messageId,link2)=>{let about={threadId,messageId,link:link2};if(files.length>=maxFiles)return void skipped2.push({...about,reason:`more than --max-files ${maxFiles}`});let response=await fileRoute(threadId,messageId,{path:link2,listFolder:!0});if(!response?.ok)return void skipped2.push({...about,
|
|
8283
|
-
reason:await refusal2(response)});if(response.headers.get("x-openmausbot-folder")!=="1")return keep(response,
|
|
8287
|
+
reason:await refusal2(response)});if(response.headers.get("x-openmausbot-folder")!=="1")return keep(response,join102(out,"files",folder),fileName(response.headers.get("content-disposition"),link2),about,files);let listing=await response.json(),dir=join102(out,"files",folder,safeName(String(listing.name??"folder")));for(let entry of Array.isArray(listing.entries)?listing.entries:[]){let name=String(entry.name),one2={...about,entry:name};if(files.length>=maxFiles){skipped2.push({...one2,reason:`mo\
|
|
8284
8288
|
re than --max-files ${maxFiles}`});continue}let answered2=await fileRoute(threadId,messageId,{path:link2,entry:name});if(!answered2?.ok){skipped2.push({...one2,reason:await refusal2(answered2)});continue}await keep(answered2,dir,safeName(name),one2,files)}listing.truncated===!0&&skipped2.push({...about,reason:"the folder has more files than the server lists"})};for(let[threadId,label2]of threads){let name=`${slug(label2)}-${threadId.slice(0,8)}`,transcript;try{transcript=await client.json(`/api/\
|
|
8285
8289
|
threads/${enc(threadId)}/export?format=json`)}catch(error62){skipped2.push({threadId,reason:`transcript not readable: ${error62 instanceof Error?error62.message:String(error62)}`});continue}let all2=Array.isArray(transcript.messages)?transcript.messages:[],kept=all2.slice(-TRANSCRIPT_MESSAGES).map(message5=>typeof message5.text=="string"&&message5.text.length>MESSAGE_TEXT_MAX?{...message5,text:`${message5.text.slice(0,MESSAGE_TEXT_MAX)}\u2026`}:message5),redacted=redactDeep({name:transcript.name,
|
|
8286
|
-
threadId,label:label2,...all2.length>kept.length?{truncated:all2.length-kept.length}:{},messages:kept});
|
|
8287
|
-
`,{mode:384});let title=String(redacted.name??label2);
|
|
8290
|
+
threadId,label:label2,...all2.length>kept.length?{truncated:all2.length-kept.length}:{},messages:kept});writeFileSync27(join102(out,"transcripts",`${name}.json`),`${JSON.stringify(redacted,null,2)}
|
|
8291
|
+
`,{mode:384});let title=String(redacted.name??label2);writeFileSync27(join102(out,"transcripts",`${name}.md`),markdownOf(title,redacted.messages,botNames.get(threadId)??"Bot"),{mode:384}),transcripts.push({threadId,label:label2,file:`transcripts/${name}.json`,messages:kept.length,...all2.length>kept.length?{truncated:all2.length-kept.length}:{}});let seen=new Set;for(let message5 of kept){if(message5.role!=="bot"||message5.kind!=="text")continue;let links=[...messageFileTargets(String(message5.text??
|
|
8288
8292
|
"")),...(message5.attachments??[]).map(attachment=>String(attachment.path))];for(let link2 of links)seen.has(link2)||(seen.add(link2),await saveLinked(threadId,name,message5.id,link2))}for(let message5 of kept){if(message5.kind!=="screen")continue;let about={threadId,messageId:message5.id};if(screens.length>=maxScreens){skipped2.push({...about,reason:`more than --max-screens ${maxScreens}`});continue}let response=await client.raw(`/api/threads/${enc(threadId)}/messages/${enc(message5.id)}/image`).
|
|
8289
|
-
catch(()=>null);if(response?.status===404){await response.body?.cancel();continue}if(!response?.ok){skipped2.push({...about,reason:await refusal2(response)});continue}let type2=response.headers.get("content-type")??"image/png",ext=type2.includes("jpeg")?".jpg":type2.includes("webp")?".webp":".png";await keep(response,
|
|
8293
|
+
catch(()=>null);if(response?.status===404){await response.body?.cancel();continue}if(!response?.ok){skipped2.push({...about,reason:await refusal2(response)});continue}let type2=response.headers.get("content-type")??"image/png",ext=type2.includes("jpeg")?".jpg":type2.includes("webp")?".webp":".png";await keep(response,join102(out,"screens",name),`${String(screens.length+1).padStart(3,"0")}-${message5.id}${ext}`,about,screens)}}writeFileSync27(join102(out,"job.json"),`${JSON.stringify(redactDeep({
|
|
8290
8294
|
...job,nodes}),null,2)}
|
|
8291
|
-
`,{mode:384});let manifest={ok:!0,out,exportedAt:new Date().toISOString(),server:client.baseUrl,threadId:options2.threadId,state:job.state,reason:job.reason,...options2.root?{root:options2.root}:{},transcripts,files,screens,skipped:skipped2,bytes:bytes2};return
|
|
8295
|
+
`,{mode:384});let manifest={ok:!0,out,exportedAt:new Date().toISOString(),server:client.baseUrl,threadId:options2.threadId,state:job.state,reason:job.reason,...options2.root?{root:options2.root}:{},transcripts,files,screens,skipped:skipped2,bytes:bytes2};return writeFileSync27(join102(out,"manifest.json"),`${JSON.stringify(redactDeep(manifest),null,2)}
|
|
8292
8296
|
`,{mode:384}),output2.progress({event:"exported",out,transcripts:transcripts.length,files:files.length,screens:screens.length,skipped:skipped2.length}),manifest}async function exportVerb(ctx){let out=flag(ctx.flags,"out")?.trim();if(!out)throw usageError("--out is required (the folder to write)");let rawSince=flag(ctx.flags,"since"),options2={out,...rawSince!==void 0?{since:parseCount(rawSince,"--since",0,Number.MAX_SAFE_INTEGER,0)}:{},...flag(ctx.flags,"root")?{root:flag(ctx.flags,"root").trim()}:
|
|
8293
8297
|
{},maxFiles:parseCount(flag(ctx.flags,"max-files"),"--max-files",200,1e5,0),maxScreens:parseCount(flag(ctx.flags,"max-screens"),"--max-screens",100,1e5,0),maxBytes:flag(ctx.flags,"max-bytes")?parseSize(flag(ctx.flags,"max-bytes"),"--max-bytes"):5e8,force:ctx.flags.force===!0};exportFolder(out,options2.force);let target2=await resolveTarget2(ctx,ctx.positionals[0]),client=await ctx.client(),threadId=target2.taskId;if(!threadId){let fleet2=await client.json("/api/bots?messages=0");if(threadId=(target2.
|
|
8294
8298
|
type==="bot"?fleet2.bots:fleet2.groups)?.find(record12=>record12.id===target2.id)?.threadId,!threadId)throw new HeadlessError(`no conversation found for ${target2.name??target2.id}`,EXIT.usage)}let manifest=await exportJob(client,{...options2,threadId},ctx.output);return{result:manifest,exitCode:EXIT.done,human:[`Exported to ${manifest.out}: ${manifest.transcripts.length} transcripts, ${manifest.files.length} files, ${manifest.screens.length} screen captures.`,...manifest.skipped.length?[`Skippe\
|
|
@@ -8312,8 +8316,8 @@ human.push(exported.ok===!1?`Export failed: ${exported.error}`:`Exported to ${ex
|
|
|
8312
8316
|
enc2,STOPPABLE,exitFor,pause,HEADLINE,waitAgain,interrupted,init_run=__esm({"server/headless/run.ts"(){"use strict";init_message_file();init_args();init_client2();init_context();init_export();init_output();MCP_WAIT_MAX_S=120,enc2=encodeURIComponent,STOPPABLE=new Set(["running","waiting","needs_input","resume"]);exitFor=(result2,strict)=>{if(result2.state==="completed"||result2.state==="idle"){let counts=result2.job?.counts??{},failed2=Number(counts.failed??0)+Number(counts.cancelled??0)>0||(result2.
|
|
8313
8317
|
job?.nodes??[]).some(node3=>node3.status==="failed"||node3.status==="cancelled");return strict&&failed2?EXIT.failed:EXIT.done}return result2.state==="needs-input"?EXIT.needsInput:result2.state==="timed-out"?EXIT.timeout:EXIT.failed};pause=(ms2,signal)=>new Promise((resolve35,reject)=>{if(signal.aborted)return reject(signal.reason);let timer2=setTimeout(()=>{signal.removeEventListener("abort",stop),resolve35()},ms2),stop=()=>{clearTimeout(timer2),reject(signal.reason)};signal.addEventListener("ab\
|
|
8314
8318
|
ort",stop,{once:!0})});HEADLINE={[EXIT.done]:"Done",[EXIT.failed]:"Did not finish",[EXIT.needsInput]:"Needs you",[EXIT.timeout]:"Still running"};waitAgain=watching=>`openmausbot wait --thread ${watching.threadId}${watching.since!==void 0?` --since ${watching.since}`:""}`;interrupted=watching=>new HeadlessError("stopped waiting; the work keeps running",EXIT.interrupted,watching.threadId?`wait again: ${waitAgain(watching)}`:"openmausbot wait TARGET picks it up again")}});var init_citations=__esm({"src/lib/citations.ts"(){"use strict"}});var init_text_clip=__esm({"server/host/text-clip.ts"(){"use strict"}});var DEVS_REPORT_LIMITS,init_devs_report=__esm({"server/devs-report.ts"(){"use strict";init_citations();init_redact2();init_text_clip();DEVS_REPORT_LIMITS={description:1e4,message:3e3,summary:2e3,seen:3e3,steps:2e3,field:40,diagnostics:48e3,problems:20,problemChars:300,logLines:80,logLineChars:400,body:600*1024}}});var PRODUCTION_CLOUD_ORIGIN,ANSWER_MAX_BYTES,BUG_REPORT_STATUS_MAX_IDS,statusAnswerSchema,init_devs_report_send=__esm({"server/devs-report-send.ts"(){"use strict";init_zod();init_devs_report();PRODUCTION_CLOUD_ORIGIN="https://cloud.openmausbot.com",ANSWER_MAX_BYTES=16*1024,BUG_REPORT_STATUS_MAX_IDS=50,statusAnswerSchema=external_exports.object({reports:external_exports.array(external_exports.object({id:external_exports.string().max(64),status:external_exports.enum(["received","fixed","unknown"]),
|
|
8315
|
-
fixedIn:external_exports.string().regex(/^\d{1,6}\.\d{1,6}\.\d{1,6}$/).nullable()})).max(BUG_REPORT_STATUS_MAX_IDS),notify:external_exports.boolean()})}});var host_doctor_exports={};__export(host_doctor_exports,{checkHost:()=>checkHost,connectorReport:()=>connectorReport,hostDoctor:()=>hostDoctor,hostReport:()=>hostReport,listeningPorts:()=>listeningPorts,systemProbe:()=>systemProbe});import{execFile as execFile15}from"node:child_process";import{existsSync as
|
|
8316
|
-
dirname as dirname37,join as
|
|
8319
|
+
fixedIn:external_exports.string().regex(/^\d{1,6}\.\d{1,6}\.\d{1,6}$/).nullable()})).max(BUG_REPORT_STATUS_MAX_IDS),notify:external_exports.boolean()})}});var host_doctor_exports={};__export(host_doctor_exports,{checkHost:()=>checkHost,connectorReport:()=>connectorReport,hostDoctor:()=>hostDoctor,hostReport:()=>hostReport,listeningPorts:()=>listeningPorts,systemProbe:()=>systemProbe});import{execFile as execFile15}from"node:child_process";import{existsSync as existsSync41,readdirSync as readdirSync20,readFileSync as readFileSync62,statfsSync}from"node:fs";import{arch,cpus as cpus2,homedir as homedir32,release,totalmem as totalmem4}from"node:os";import{
|
|
8320
|
+
dirname as dirname37,join as join103,posix as posix6,resolve as resolve31}from"node:path";function osRelease(probe){let text13=probe.read("/etc/os-release")??probe.read("/usr/lib/os-release")??"";return Object.fromEntries(text13.split(`
|
|
8317
8321
|
`).map(line3=>/^([A-Z_]+)=(.*)$/.exec(line3.trim())).filter(match=>match!==null).map(match=>[match[1],match[2].replace(/^"(.*)"$/,"$1")]))}function systemCheck(probe){let os4=osRelease(probe),name=os4.PRETTY_NAME||"An unknown Linux",tested=os4.ID==="ubuntu"&&["22.04","24.04"].includes(os4.VERSION_ID??"")||os4.ID==="debian"&&os4.VERSION_ID==="12",line3=`${name}, kernel ${probe.kernel}`;return tested?ok("system",line3):warn3("system",`${line3}: not a system we test (Ubuntu 24.04 or 22.04, or Debia\
|
|
8318
8322
|
n 12)`)}function archCheck(probe){return probe.arch==="x64"?ok("arch","x86_64"):probe.arch==="arm64"?warn3("arch","arm64: the server runs here, but a self-hosted Team server is supported on x86_64 only"):fail2("arch",`${probe.arch}: Limix Bot's images are built for x86_64 and arm64 only`,"use an x86_64 server")}async function containerCheck(probe){let docker=await probe.run("docker",["version","--format","{{.Server.Version}}"]);if(docker.ok&&docker.stdout.trim())return ok("containers",`Docker ${docker.
|
|
8319
8323
|
stdout.trim()}`);if(!docker.missing)return/permission denied/i.test(docker.stderr)?fail2("containers","Docker is installed, but this user cannot reach its daemon","run as root, or add the user to the docker group: sudo usermod -aG docker $USER"):fail2("containers","Docker is installed, but its daemon is not running","sudo systemctl enable --now docker");let podman=await probe.run("podman",["version","--format","{{.Version}}"]);return podman.ok&&podman.stdout.trim()?ok("containers",`Podman ${podman.
|
|
@@ -8335,10 +8339,10 @@ ok("clock","Clock is kept synchronised (network time could not be reached to com
|
|
|
8335
8339
|
seconds>30||synced===!1?warn3("clock",`Clock is ${off2}${synced===!1?", and not kept synchronised":""}`,NTP_FIX):ok("clock",`Clock is ${off2} (signed requests allow ${SIGNED_REQUEST_SKEW_S} s)`)}async function checkHost(probe,options2){if(probe.platform!=="linux"){let name=probe.platform==="darwin"?"macOS":probe.platform==="win32"?"Windows":probe.platform;return[fail2("platform",`doctor --host checks a Linux server, and this is ${name}`,"run it on the Linux server that will host Limix Bot")]}let[
|
|
8336
8340
|
containers,ports,clock3,connector]=await Promise.all([containerCheck(probe),portChecks(probe,options2),clockCheck(probe),connectorReport(probe)]);return[systemCheck(probe),archCheck(probe),containers,userNamespaceCheck(probe,connector),seccompCheck(probe),cgroupCheck(probe),diskCheck(probe,options2.dataDir),encryptedCheck(probe,options2.dataDir),sizeCheck(probe),...ports,clock3,...connectorChecks(connector)]}function hostReport(checks){let problems=checks.filter(check3=>check3.status==="FAIL").length,
|
|
8337
8341
|
warnings=checks.filter(check3=>check3.status==="warn").length,plural2=(count5,word)=>`${count5} ${word}${count5===1?"":"s"}`;return{result:{ok:problems===0,problems,warnings,checks},exitCode:problems?EXIT.hostMissing:EXIT.done,human:[...checks.flatMap(check3=>[`${check3.status.padEnd(6)}${check3.message}`,...check3.fix&&check3.status!=="ok"?[` fix: ${check3.fix}`]:[]]),problems?`${plural2(problems,"problem")}${warnings?`, ${plural2(warnings,"warning")}`:""}.`:`Ready${warnings?`, with ${plural2(
|
|
8338
|
-
warnings,"warning")}`:""}.`]}}function run5(command,args){return new Promise(done=>{execFile15(command,args,{timeout:1e4,env:{...process.env,LC_ALL:"C"}},(error62,stdout2,stderr)=>{done({ok:!error62,stdout:String(stdout2),stderr:String(stderr),missing:error62?.code==="ENOENT"})})})}function systemProbe(){let read2=path3=>{try{return
|
|
8339
|
-
list:path3=>{try{return readdirSync20(path3)}catch{return[]}},run:run5,freeBytes(path3){let at2=resolve31(path3);for(;!
|
|
8342
|
+
warnings,"warning")}`:""}.`]}}function run5(command,args){return new Promise(done=>{execFile15(command,args,{timeout:1e4,env:{...process.env,LC_ALL:"C"}},(error62,stdout2,stderr)=>{done({ok:!error62,stdout:String(stdout2),stderr:String(stderr),missing:error62?.code==="ENOENT"})})})}function systemProbe(){let read2=path3=>{try{return readFileSync62(path3,"utf8")}catch{return null}};return{platform:process.platform,arch:arch(),kernel:release(),cpus:cpus2().length,memoryBytes:totalmem4(),read:read2,
|
|
8343
|
+
list:path3=>{try{return readdirSync20(path3)}catch{return[]}},run:run5,freeBytes(path3){let at2=resolve31(path3);for(;!existsSync41(at2)&&dirname37(at2)!==at2;)at2=dirname37(at2);try{let stats=statfsSync(at2);return Number(stats.bavail)*Number(stats.bsize)}catch{return null}},async clockOffset(){try{let before=Date.now(),response=await fetch(PRODUCTION_CLOUD_ORIGIN,{method:"HEAD",redirect:"manual",signal:AbortSignal.timeout(5e3)}),after=Date.now(),date5=Date.parse(response.headers.get("date")??"");
|
|
8340
8344
|
return Number.isFinite(date5)?(before+after)/2-(date5+500):null}catch{return null}},async serverAnswers(port){try{return(await(await fetch(`http://127.0.0.1:${port}/api/health`,{signal:AbortSignal.timeout(2e3)})).json()).app==="openmausbot"}catch{return!1}}}}async function hostDoctor(ctx,probe=systemProbe()){let rawPort=flag(ctx.flags,"port")??ctx.env.OMB_PORT??"8799",port=Number(rawPort);if(!Number.isInteger(port)||port<1||port>65535)throw usageError("--port must be 1-65535");let dataDir=posix6.
|
|
8341
|
-
resolve(flag(ctx.flags,"data-dir")??(ctx.env.OMB_DATA_DIR||
|
|
8345
|
+
resolve(flag(ctx.flags,"data-dir")??(ctx.env.OMB_DATA_DIR||join103(homedir32(),".limixbot"))),domain2=flag(ctx.flags,"domain")?.trim().toLowerCase();return hostReport(await checkHost(probe,{dataDir,port,...domain2?{domain:domain2}:{}}))}var GB,SIGNED_REQUEST_SKEW_S,NTP_FIX,ok,warn3,fail2,CONNECTOR,init_host_doctor=__esm({"server/headless/host-doctor.ts"(){"use strict";init_devs_report_send();init_args();GB=1e9,SIGNED_REQUEST_SKEW_S=300,NTP_FIX="sudo timedatectl set-ntp true",ok=(id,message5)=>({
|
|
8342
8346
|
id,status:"ok",message:message5}),warn3=(id,message5,fix)=>({id,status:"warn",message:message5,...fix?{fix}:{}}),fail2=(id,message5,fix)=>({id,status:"FAIL",message:message5,fix});CONNECTOR="mausbot-connector"}});async function doctorOnce(ctx){let client=await ctx.client(),counted2=refusal3=>refusal3?.status===403?client.json("/api/health/engines").then(answer=>({counted:Number(answer?.engines)||0}),()=>Promise.reject(refusal3)):Promise.reject(refusal3),[rawHealth,models2]=await Promise.all([client.tool("get_system_health",{}),client.tool("list_available_models",{}).catch(counted2)]),health={...rawHealth,endpoint:client.baseUrl},instances=Array.isArray(models2?.instances)?models2.instances:[],availableEngines=instances.
|
|
8343
8347
|
filter(instance=>instance.snapshot?.state==="available").map(instance=>instance.instanceId),availableCount=typeof models2?.counted=="number"?models2.counted:availableEngines.length,quietly=read2=>read2.catch(()=>null),[server,session,config3]=await Promise.all([quietly(client.json("/.well-known/openmausbot/environment")),quietly(client.json("/api/auth/session")),quietly(client.json("/api/config"))]),problems=[],warnings=[],isOmb=health.app==="openmausbot";isOmb||problems.push(`${client.baseUrl} \
|
|
8344
8348
|
answered, but it is not Limix Bot`);let tooOld=!!server&&server.capabilities?.jobs!==!0;tooOld&&problems.push(`Limix Bot ${server.version??"(unknown version)"} is too old for the headless commands: it cannot report a conversation's job`),isOmb&&!availableCount&&problems.push("no engine is available: set one up with `openmausbot engine set KIND --key-env VAR`"),session?.kind==="session"&&typeof session.expiresAt=="number"&&session.expiresAt-Date.now()<14*DAY3&&warnings.push(`this session expires \
|
|
@@ -8364,8 +8368,8 @@ json("/api/bots?messages=0")).bots??[],memberIds=wanted.map(member=>{let found=b
|
|
|
8364
8368
|
id,...target2.taskId?{task_id:target2.taskId}:{},...selection},preview2=dryRun(ctx,"set_bot_model",args);return preview2||{result:await(await ctx.client()).tool("set_bot_model",args),exitCode:EXIT.done,human:[`${target2.name??target2.id} now runs on ${selection.instance_id}/${selection.model}${target2.taskId?` in thread ${shortId(target2.taskId)}`:""}.`]}}async function edit(ctx){let explicit=flag(ctx.flags,"bot")?.trim(),[first,second]=ctx.positionals,target2=explicit?{type:"bot",id:explicit,...flag(
|
|
8365
8369
|
ctx.flags,"task")?{taskId:flag(ctx.flags,"task").trim()}:{}}:void 0;if(!target2&&!first)throw usageError("a bot is required","openmausbot edit BOT --message ID TEXT, or --bot ID");let messageId=requiredFlag(ctx.flags,"message"),text13=await readMessage(ctx,target2?first:second),resolved2=target2??await resolveTarget2(ctx,first,"bot"),args={bot_id:resolved2.id,message_id:messageId,text:text13,...resolved2.taskId?{task_id:resolved2.taskId}:{}},preview2=dryRun(ctx,"edit_bot_message",args);return preview2||
|
|
8366
8370
|
{result:await(await ctx.client()).tool("edit_bot_message",args),exitCode:EXIT.done,human:[`Edited the message and asked ${resolved2.name??resolved2.id} again.`]}}var dryRun,targetArgs,DAY3,interruptArgs,init_commands=__esm({"server/headless/commands.ts"(){"use strict";init_args();init_context();init_output();init_run();dryRun=(ctx,tool,args,extra={})=>ctx.flags["dry-run"]===!0?{result:{ok:!0,dryRun:!0,command:ctx.verb,tool,arguments:args,...extra},exitCode:EXIT.done,human:[`Would ${extra.newConversation?
|
|
8367
|
-
`start a new conversation, "${extra.newConversation.title}", then `:""}call ${tool} with ${JSON.stringify(args)}${extra.tree?", then stop every teammate still working on it":""}. Nothing was sent.`]}:void 0,targetArgs=target2=>({[`${target2.type}_id`]:target2.id,...target2.taskId?{task_id:target2.taskId}:{}}),DAY3=24*36e5;interruptArgs=target2=>({target_type:target2.type,target_id:target2.id,...target2.taskId?{task_id:target2.taskId}:{}})}});import{closeSync as closeSync15,existsSync as
|
|
8368
|
-
if(path3==="-"||/^\/dev\/(?:stdout|stderr|tty)$/.test(path3))throw usageError("the token goes to a file, never to the terminal","pass --out FILE");if(
|
|
8371
|
+
`start a new conversation, "${extra.newConversation.title}", then `:""}call ${tool} with ${JSON.stringify(args)}${extra.tree?", then stop every teammate still working on it":""}. Nothing was sent.`]}:void 0,targetArgs=target2=>({[`${target2.type}_id`]:target2.id,...target2.taskId?{task_id:target2.taskId}:{}}),DAY3=24*36e5;interruptArgs=target2=>({target_type:target2.type,target_id:target2.id,...target2.taskId?{task_id:target2.taskId}:{}})}});import{closeSync as closeSync15,existsSync as existsSync42,fchmodSync,fstatSync as fstatSync7,openSync as openSync14,writeSync as writeSync2}from"node:fs";import{isatty}from"node:tty";async function call(origin,path3,init={}){let response=await fetch(`${origin}${path3}`,{...init,redirect:"error",signal:AbortSignal.timeout(15e3),headers:{"content-type":"application/json","x-openmausbot-cli":"1",...init.headers}});return{status:response.status,body:await response.json().catch(()=>({}))}}function writeTokenFile(path3,token,force){
|
|
8372
|
+
if(path3==="-"||/^\/dev\/(?:stdout|stderr|tty)$/.test(path3))throw usageError("the token goes to a file, never to the terminal","pass --out FILE");if(existsSync42(path3)&&!force)throw usageError(`${path3} already exists`,"pass --force to replace it");let fd=openSync14(path3,force?"w":"wx",384);try{if(isatty(fd)||fstatSync7(fd).isCharacterDevice())throw usageError("the token goes to a file, never to the terminal","pass --out FILE");process.platform!=="win32"&&fchmodSync(fd,384),writeSync2(fd,`${token}\
|
|
8369
8373
|
|
|
8370
8374
|
`)}finally{closeSync15(fd)}}function target(ctx){let typedCode=flag(ctx.flags,"code")?.trim()??"",positional=ctx.positionals[0]?.trim(),named2=positional?{url:positional}:namedServer(ctx.flags,ctx.env)??{port:"8799"},read2=parseServerInput("url"in named2?named2.url:`http://127.0.0.1:${named2.port}`,typedCode);if(read2.ok)return{candidates:read2.candidates,secret:read2.code??read2.credential};throw read2.problem==="publicHttp"?usageError(`http://${read2.host} is on the open internet and plain htt\
|
|
8371
8375
|
p isn't encrypted`,"use the server's https:// address, or put HTTPS in front (cloudflared, Caddy or Tailscale)"):usageError(PROBLEM[read2.problem]??PROBLEM.notAnAddress)}async function connectVerb(ctx){let out=flag(ctx.flags,"out")?.trim();if(!out)throw usageError("--out FILE is required: where to keep the script key");let{candidates,secret:secret2}=target(ctx),origin=candidates[0],described=null;for(let candidate of candidates)if(described=await call(candidate,"/.well-known/openmausbot/environm\
|
|
@@ -8375,7 +8379,7 @@ EXIT.unreachable,`${cliCommand("pair")} in a terminal on this computer, then pas
|
|
|
8375
8379
|
let session=paired.body.session??{},environment=paired.body.environment??described.body,scope=Array.isArray(session.scopes)&&session.scopes.includes("admin")?"admin":"client";return{result:{ok:!0,url:origin,tokenFile:out,workspace:{label:environment.label,environmentId:environment.environmentId,version:environment.version},session:{id:session.id,label:session.label,scopes:session.scopes,expiresAt:session.expiresAt}},exitCode:EXIT.done,human:[`Connected to "${environment.label}" (${origin}, ${scope===
|
|
8376
8380
|
"admin"?"everything":"chat and approvals"}${typeof session.expiresAt=="number"?`, until ${new Date(session.expiresAt).toISOString().slice(0,10)}`:""}).`,`Script key saved to ${out}. Check it: ${cliCommand(`doctor --url ${origin} --token-file ${out}`)}`]}}var PAIR_ON_SERVER,isLoopback2,PROBLEM,init_connect=__esm({"server/headless/connect.ts"(){"use strict";init_server_address();init_cli_invocation();init_args();init_client2();PAIR_ON_SERVER="npx limixbot pair (Docker: docker compose exec omb limi\
|
|
8377
8381
|
xbot pair)",isLoopback2=origin=>/^https?:\/\/(?:127\.0\.0\.1|localhost|\[::1\])(?::\d+)?$/i.test(origin);PROBLEM={empty:"give the server's address or its pairing link",codeOnly:"that is a pairing code: give the server's address too, like limixbot connect http://192.168.1.20:8799 --code CODE",emailCode:"that is a sign-in code from an email; pairing needs a 12-character code like 7KQ2-M9XD-H4TP",oldCode:"that is a code from an older Limix Bot; pairing needs a 12-character code like 7KQ2-M9XD-H4TP",
|
|
8378
|
-
scriptKey:"that is a script key; pass it with --token-file instead of pairing",notACode:"that is not a pairing code; pairing needs a 12-character code like 7KQ2-M9XD-H4TP",phoneLink:"that link is for the Limix Bot phone app; give the server's address or the link the server printed",notAnAddress:"that is not a server address; give the link the server printed, or its address like http://192.168.1.20:8799"}}});import{readFileSync as
|
|
8382
|
+
scriptKey:"that is a script key; pass it with --token-file instead of pairing",notACode:"that is not a pairing code; pairing needs a 12-character code like 7KQ2-M9XD-H4TP",phoneLink:"that link is for the Limix Bot phone app; give the server's address or the link the server printed",notAnAddress:"that is not a server address; give the link the server printed, or its address like http://192.168.1.20:8799"}}});import{readFileSync as readFileSync63}from"node:fs";function readSecret(source,env,what){if(source.env!==void 0){let value=env[source.env]?.trim();if(!value)throw usageError(`${what}: the environment variable ${source.env} is not set`);return value}if(source.file!==void 0){let value;try{value=readFileSync63(source.file,"utf8").trim()}catch(error62){throw usageError(`${what}: ${source.file} could not be read (${error62.code??"error"})`)}if(!value)throw usageError(`${what}: ${source.file} is empty`);
|
|
8379
8383
|
return value}throw usageError(`${what}: put the key in an environment variable or a file`)}async function installEngine(client,instanceId){let response=await client.raw(`/api/instances/${encodeURIComponent(instanceId)}/install`,{method:"POST",headers:{"content-type":"application/json"},body:"{}",stream:!0,signal:AbortSignal.timeout(INSTALL_TIMEOUT_MS)}),text13=await response.text();if(!response.ok)throw Object.assign(new Error(`Limix Bot API error (${response.status}): ${text13||response.statusText}`),
|
|
8380
8384
|
{status:response.status});let body={};try{body=JSON.parse(text13)}catch{}return body.instances?.find(instance=>instance.instanceId===instanceId)?.snapshot?.state}async function applyEngine(client,request2){let kind=ENGINE_KINDS[request2.kind];if(!kind)throw usageError(`unknown engine ${request2.kind}: use one of ${Object.keys(ENGINE_KINDS).join(", ")}`);if(request2.baseUrl!==void 0&&kind.baseUrl==="no")throw usageError(`${request2.kind} takes no base URL`);if(request2.baseUrl===void 0&&kind.baseUrl===
|
|
8381
8385
|
"required")throw usageError(`${request2.kind} needs --base-url`);if(request2.baseUrl!==void 0&&!/^https?:\/\/[^\s]+$/.test(request2.baseUrl))throw usageError("the base URL must start with http:// or https://");if(request2.onlyClaudeApi&&request2.kind!=="claude")throw usageError("--only-claude-api is for the claude engine");let instanceId=request2.onlyClaudeApi?kind.apiInstance:kind.instance,status2=(await client.json("/api/config"))[kind.config]??{},configured=status2.configured===!0,patch={},changed2=[];
|
|
@@ -8404,8 +8408,8 @@ resolve35,delay3);signal.addEventListener("abort",()=>{clearTimeout(timer2),reso
|
|
|
8404
8408
|
DEFAULT_EVENT_KINDS=["message","message.patch","thread","bot","group"],FINAL=new Set(["needs-input","completed","failed","stalled","idle"]);jobExit=state=>state==="needs-input"?EXIT.needsInput:state==="failed"||state==="stalled"?EXIT.failed:EXIT.done}});function lineDiff(before,after){if(before===after)return[];let a2=before===""?[]:before.split(`
|
|
8405
8409
|
`),b3=after===""?[]:after.split(`
|
|
8406
8410
|
`),n3=a2.length,m3=b3.length;if(n3*m3>16e4)return[...a2.map(line3=>`-${line3}`),...b3.map(line3=>`+${line3}`)];let lcs=Array.from({length:n3+1},()=>Array.from({length:m3+1},()=>0));for(let i3=n3-1;i3>=0;i3--)for(let j3=m3-1;j3>=0;j3--)lcs[i3][j3]=a2[i3]===b3[j3]?lcs[i3+1][j3+1]+1:Math.max(lcs[i3+1][j3],lcs[i3][j3+1]);let out=[],i2=0,j2=0;for(;i2<n3&&j2<m3;)a2[i2]===b3[j2]?(out.push(` ${a2[i2]}`),i2++,j2++):lcs[i2+1][j2]>=lcs[i2][j2+1]?(out.push(`-${a2[i2]}`),i2++):(out.push(`+${b3[j2]}`),j2++);for(;i2<
|
|
8407
|
-
n3;)out.push(`-${a2[i2++]}`);for(;j2<m3;)out.push(`+${b3[j2++]}`);return out}var init_line_diff=__esm({"shared/line-diff.ts"(){"use strict"}});import{readFileSync as
|
|
8408
|
-
path3),dir=dirname38(file2),raw;try{raw=
|
|
8411
|
+
n3;)out.push(`-${a2[i2++]}`);for(;j2<m3;)out.push(`+${b3[j2++]}`);return out}var init_line_diff=__esm({"shared/line-diff.ts"(){"use strict"}});import{readFileSync as readFileSync64}from"node:fs";import{dirname as dirname38,posix as posix7,resolve as resolve32,win32 as win326}from"node:path";function everyTool(scope){return!scope||!Array.isArray(scope.allow)&&!(Array.isArray(scope.deny)&&scope.deny.length>0)}function serverFolder(raw){let path3=raw.trim();if(path3.startsWith("/"))return posix7.resolve(path3);if(/^[a-z]:[\\/]/i.test(path3)||/^\\\\[^\\/]+[\\/][^\\/]/.test(path3))return win326.resolve(path3)}function loadTeamFile(path3){let file2=resolve32(
|
|
8412
|
+
path3),dir=dirname38(file2),raw;try{raw=readFileSync64(file2,"utf8")}catch(error62){throw usageError(`${path3} could not be read (${error62.code??"error"})`)}let data;try{data=/\.json$/i.test(file2)?JSON.parse(raw):parse4(raw)}catch(error62){throw usageError(`${path3} is not valid ${/\.json$/i.test(file2)?"JSON":"YAML"}: ${error62 instanceof Error?error62.message.split(`
|
|
8409
8413
|
`)[0]:String(error62)}`)}let parsed=teamFileSchema.safeParse(data);if(!parsed.success){let issue2=parsed.error.issues[0],where=issue2.path.length?issue2.path.map(part=>typeof part=="number"?`[${part}]`:`.${String(part)}`).join("").replace(/^\./,""):"the file",message5=issue2.code==="unrecognized_keys"?`unknown field ${issue2.keys.map(key2=>`"${key2}"`).join(", ")}`:issue2.message;throw usageError(`${path3}: ${where}: ${message5}`)}return checkTeamFile(parsed.data,file2,dir)}function checkTeamFile(input2,file2,dir){
|
|
8410
8414
|
let warnings=[],key2=name=>name.trim().toLowerCase(),kept=(value,where)=>{if(value===void 0||!REDACTED.test(value))return value;warnings.push(`${where} has a secret taken out (\xABredacted \u2026\xBB), so it is left as it is`)},seen=new Map;for(let bot of input2.bots){if(seen.has(key2(bot.name)))throw usageError(`bots: "${bot.name}" is listed twice (names are compared without case)`);seen.set(key2(bot.name),bot.name)}let teams=(input2.teams??[]).map(team=>{let brief=kept(text12(dir,team.brief,`t\
|
|
8411
8415
|
eam "${team.name}" brief`),`team "${team.name}": its brief`);if(brief!==void 0&&Buffer.byteLength(brief.trimEnd(),"utf8")>TEAM_BRIEF_MAX_BYTES)throw usageError(`team "${team.name}": brief is over ${TEAM_BRIEF_MAX_BYTES} bytes`);return{name:team.name,...brief!==void 0?{brief}:{},prune:team.prune===!0}}),teamSeen=new Set;for(let team of teams){if(teamSeen.has(key2(team.name)))throw usageError(`teams: "${team.name}" is listed twice`);teamSeen.add(key2(team.name))}let defaults=input2.defaults??{},bots=input2.
|
|
@@ -8427,7 +8431,7 @@ optional()}).strict().optional(),skills:external_exports.array(external_exports.
|
|
|
8427
8431
|
min(1).max(60),brief:textOrFile.optional(),prune:external_exports.boolean().optional()}).strict()).optional(),bots:external_exports.array(external_exports.object({name:oneLine4("a name",BOT_PROFILE_LIMITS.name).pipe(external_exports.string().trim().min(1,"must not be empty")),was:external_exports.string().trim().min(1).max(BOT_PROFILE_LIMITS.name).optional(),chief:external_exports.boolean().optional(),manages:external_exports.array(external_exports.string().trim().min(1).max(60)).optional(),...botFields}).
|
|
8428
8432
|
strict()).min(1,"list at least one bot"),rooms:external_exports.array(external_exports.object({name:external_exports.string().trim().min(1).max(100),team:external_exports.string().trim().min(1).max(60).optional(),members:external_exports.array(external_exports.string().trim().min(1)).min(1),brief:textOrFile.optional(),responder:external_exports.string().trim().min(1).optional()}).strict()).optional()}).strict(),ENGINE_KIND={claude:"claude",openai:"openai",openrouter:"openrouter",xai:"xai",groq:"\
|
|
8429
8433
|
groq",greenference:"greenference",modelgo:"modelgo",mistral:"mistral",cerebras:"cerebras",openaiCompatible:"openai-compatible"};REDACTED=/«redacted \d+ chars»/,lf=text13=>text13.replace(/\r\n?/g,`
|
|
8430
|
-
`),readRelative=(dir,path3,what)=>{try{return lf(
|
|
8434
|
+
`),readRelative=(dir,path3,what)=>{try{return lf(readFileSync64(resolve32(dir,path3.replace(/\\/g,"/")),"utf8"))}catch(error62){throw usageError(`${what}: ${path3} could not be read (${error62.code??"error"})`)}},text12=(dir,value,what)=>value===void 0?void 0:typeof value=="string"?lf(value):readRelative(dir,value.file,what)}});import{createHash as createHash32}from"node:crypto";import{mkdirSync as mkdirSync42,writeFileSync as writeFileSync28}from"node:fs";import{basename as basename18,dirname as dirname39,join as join104,posix as posix8,resolve as resolve33}from"node:path";function changedLines(before,after){let diff=lineDiff(before.trimEnd(),after.trimEnd());return Math.max(diff.filter(line3=>line3.startsWith("+")).length,diff.filter(line3=>line3.startsWith("-")).length)}function botPatch(desired,echo,team){let patch={},
|
|
8431
8435
|
changes=[];if(echo.name!==desired.name&&(patch.name=desired.name,changes.push(`renamed from "${echo.name}"`)),team!==void 0&&key(echo.section)!==key(team)&&(patch.section=team,changes.push(`team "${echo.section??"none"}" \u2192 "${team}"`)),desired.title!==void 0&&(echo.title??"")!==desired.title&&(patch.title=desired.title,changes.push(`title "${echo.title??""}" \u2192 "${desired.title}"`)),desired.description!==void 0&&(echo.description??"")!==desired.description&&(patch.description=desired.description,
|
|
8432
8436
|
changes.push("description changed")),desired.soul!==void 0&&(echo.soul??"").trimEnd()!==desired.soul.trimEnd()&&(patch.soul=desired.soul.trimEnd(),changes.push(echo.soul?`soul ${lines(changedLines(echo.soul??"",desired.soul))} changed`:`soul set (${lines(desired.soul.trimEnd().split(`
|
|
8433
8437
|
`).length)})`)),desired.model||desired.effort){let current=echo.modelSelection??{},instanceId=desired.model?.instanceId??current.instanceId,model=desired.model?.model??current.model;if(current.instanceId!==instanceId||current.model!==model||desired.effort!==void 0&¤t.effort!==desired.effort){let effort=desired.effort??(instanceId===current.instanceId?current.effort:void 0);patch.modelSelection={instanceId,model,...effort?{effort}:{}},patch.requireAvailableModel=!0,changes.push(`model ${current.
|
|
@@ -8469,17 +8473,17 @@ hidden&&inScope(bot.section)),names=new Set;for(let bot of bots){if(names.has(ke
|
|
|
8469
8473
|
all(teams.map(async name=>{let brief=String((await client.json(`/api/section-context?section=${enc3(name)}`)).text??"");return{name,...brief.trim()?{brief:clean2(brief,`team "${name}" brief`)}:{}}})),skipped2=[],skills=0,botEntries=[],skillDirs=botSkillDirs(bots.map(bot=>bot.name));for(let[index2,bot]of bots.entries()){let entry={name:bot.name,...bot.section?{team:bot.section}:{},...bot.title?{title:bot.title}:{},...bot.description?{description:clean2(bot.description,`bot "${bot.name}" descripti\
|
|
8470
8474
|
on`)}:{}};bot.chiefOfStaff&&Object.assign(entry,{chief:!0,...bot.managedSections?.length?{manages:bot.managedSections}:{}}),bot.soul?.trim()&&(entry.soul=clean2(bot.soul,`bot "${bot.name}" soul`)),bot.modelSelection?.instanceId&&(entry.model=`${bot.modelSelection.instanceId}/${bot.modelSelection.model}`,bot.modelSelection.effort&&(entry.effort=bot.modelSelection.effort));let approval=approvalModeFor(bot);approval==="custom"?skipped2.push(`${bot.name}: its Custom approval level is set in the desk\
|
|
8471
8475
|
top app, not in a team file`):entry.approval=approval,bot.computer&&(entry.computer=bot.computer),bot.cwd&&(entry.cwd=bot.cwd),(bot.browser===!1||bot.browserProfile)&&(entry.browser={enabled:bot.browser!==!1,...bot.browserProfile?{profile:bot.browserProfile}:{}}),everyTool(bot.toolScope)||(entry.tools=bot.toolScope);let listing=(await client.json(`/api/bots/${enc3(bot.id)}/skills`)).skills??[];listing.length&&(entry.skills=[]);for(let skill of listing){let text13=clean2(String((await client.json(
|
|
8472
|
-
`/api/bots/${enc3(bot.id)}/skills/${enc3(skill.name)}`)).text??""),`bot "${bot.name}" skill ${skill.name}`),relativePath=skillFilePath(skillDirs[index2],skill.name);
|
|
8476
|
+
`/api/bots/${enc3(bot.id)}/skills/${enc3(skill.name)}`)).text??""),`bot "${bot.name}" skill ${skill.name}`),relativePath=skillFilePath(skillDirs[index2],skill.name);mkdirSync42(dirname39(join104(dir,relativePath)),{recursive:!0}),writeFileSync28(join104(dir,relativePath),text13),entry.skills.push({file:relativePath,...skill.enabled?{}:{enabled:!1}}),skills+=1}botEntries.push(entry)}let byId=new Map((fleet2.bots??[]).map(bot=>[bot.id,bot.name])),roomEntries=(fleet2.groups??[]).filter(group=>!group.
|
|
8473
8477
|
dm&&inScope(group.section)).map(group=>{let responder=group.defaultResponder??{};return{name:group.name,...group.section?{team:group.section}:{},members:(group.memberIds??[]).map(id=>byId.get(id)??id),...String(group.bulletin??"").trim()?{brief:clean2(String(group.bulletin),`room "${group.name}" brief`)}:{},...responder.kind==="everyone"||responder.kind==="mentions"?{responder:responder.kind}:responder.kind==="member"&&byId.has(responder.botId)?{responder:byId.get(responder.botId)}:{}}}),config3=await client.
|
|
8474
8478
|
json("/api/config"),engines={};for(let[kind,spec]of Object.entries(ENGINE_KINDS)){if(config3[spec.config]?.configured!==!0)continue;let name=kind==="openai-compatible"?"openaiCompatible":kind;engines[name]={key:{env:"SET_ME"},...kind==="openai-compatible"&&config3.openaiCompat?.url?{baseUrl:config3.openaiCompat.url}:{},...kind==="claude"&&config3.anthropic?.everyClaudeBot===!1?{everyClaudeBot:!1}:{}}}let document3={version:1,...Object.keys(engines).length?{engines}:{},...teamEntries.length?{teams:teamEntries}:
|
|
8475
|
-
{},bots:botEntries,...roomEntries.length?{rooms:roomEntries}:{}};if(!botEntries.length)throw new HeadlessError("no bots to export",EXIT.failed);return
|
|
8479
|
+
{},bots:botEntries,...roomEntries.length?{rooms:roomEntries}:{}};if(!botEntries.length)throw new HeadlessError("no bots to export",EXIT.failed);return writeFileSync28(resolve33(out),`# Written by openmausbot team export on ${new Date().toISOString().slice(0,10)}.
|
|
8476
8480
|
# Engine keys are placeholders (SET_ME): set them before applying this elsewhere.
|
|
8477
8481
|
${stringify3(document3,{lineWidth:0})}`),{result:{ok:!0,file:resolve33(out),teams:teamEntries.length,bots:botEntries.length,rooms:roomEntries.length,skills,engines:Object.keys(engines),skipped:skipped2,redacted},exitCode:EXIT.done,human:[`Wrote ${out}: ${teamEntries.length} teams, ${botEntries.length} bots, ${roomEntries.length} rooms, ${skills} skills.`,...Object.keys(engines).length?["Engine keys are placeholders (SET_ME): set them before applying it elsewhere."]:[],...redacted.length?[`A secr\
|
|
8478
8482
|
et was taken out of: ${redacted.join(", ")} (apply leaves those as they are).`]:[],...skipped2.map(line3=>`not exported: ${line3}`)]}}var enc3,key,APPROVAL_LABEL,sameSet,canonicalScope,lines,describeNew,summary,countsOf,skillFilePath,init_team_apply=__esm({"server/headless/team-apply.ts"(){"use strict";init_browser2();init_approval_mode();init_tool_scope_support();init_line_diff();init_redact();init_args();init_client2();init_engine();init_team_file();enc3=encodeURIComponent,key=name=>(name??"").
|
|
8479
8483
|
trim().toLowerCase(),APPROVAL_LABEL={ask:"Ask",edits:"Accept edits",auto:"Auto",full:"Full access",custom:"Custom"},sameSet=(a2,b3)=>a2.length===b3.length&&a2.every(item=>b3.includes(item)),canonicalScope=scope=>everyTool(scope)?"every tool":JSON.stringify(Object.fromEntries(["allow","deny"].filter(field=>Array.isArray(scope[field])).map(field=>[field,[...new Set(scope[field])].sort()]))),lines=n3=>`${n3} line${n3===1?"":"s"}`;describeNew=bot=>[bot.chief===!0?`Chief of ${bot.team??"General"}`:bot.
|
|
8480
8484
|
team?`team ${bot.team}`:"",bot.model?`${bot.model.instanceId}/${bot.model.model}`:"",bot.approval?APPROVAL_LABEL[bot.approval]:"",bot.computer&&bot.computer!=="auto"?`computer ${bot.computer}`:""].filter(Boolean).join(" \xB7 ");summary=tally=>`${tally.created} to create, ${tally.changed} to change, ${tally.unchanged} unchanged, ${tally.deleted} to delete`;countsOf=tally=>({created:tally.created,changed:tally.changed,unchanged:tally.unchanged,deleted:tally.deleted}),skillFilePath=(botDir,skillName)=>posix8.
|
|
8481
|
-
join("skills",botDir,skillName,"SKILL.md")}});import{existsSync as
|
|
8482
|
-
is required: where to keep the token");if(
|
|
8485
|
+
join("skills",botDir,skillName,"SKILL.md")}});import{existsSync as existsSync43}from"node:fs";async function tokens(ctx){let listed2=await(await ctx.client()).json("/api/auth/sessions");return(Array.isArray(listed2.sessions)?listed2.sessions:[]).filter(session=>session.token===!0)}async function create(ctx){let name=ctx.positionals[0]?.trim();if(!name)throw usageError("name the token","openmausbot token create NAME --out FILE [--scope client|admin] [--expires 90d]");let out=flag(ctx.flags,"out")?.trim();if(!out)throw usageError("--out FILE \
|
|
8486
|
+
is required: where to keep the token");if(existsSync43(out)&&ctx.flags.force!==!0)throw usageError(`${out} already exists`,"pass --force to replace it");let scope=oneOf(flag(ctx.flags,"scope"),"--scope",["client","admin"],"client"),raw=flag(ctx.flags,"expires"),ttlMs=raw?parseDuration(raw,"--expires",{min:36e5,max:3650*DAY4}):90*DAY4,client=await ctx.client(),minted=await client.json("/api/auth/pairing",{method:"POST",body:JSON.stringify({label:name,scopes:scope==="admin"?["admin","client"]:["cl\
|
|
8483
8487
|
ient"],tokenTtlMs:ttlMs})}),paired=await client.json("/api/auth/pair",{method:"POST",body:JSON.stringify({code:minted.code,label:name})}),session=paired.session??{};if(session.token!==!0)throw typeof session.id=="string"&&await client.json(`/api/auth/sessions/${encodeURIComponent(session.id)}`,{method:"DELETE"}).catch(()=>{}),new HeadlessError("this Limix Bot server cannot make access tokens",EXIT.unreachable,"update Limix Bot on the server, or use limixbot connect");return writeTokenFile(out,paired.
|
|
8484
8488
|
token,ctx.flags.force===!0),{result:{ok:!0,tokenFile:out,url:client.baseUrl,token:{id:session.id,name:session.label,scope,expiresAt:session.expiresAt}},exitCode:EXIT.done,human:[`Token "${session.label}" (${scope==="admin"?"full access":"chat and approvals only"}) until ${day(session.expiresAt)}, id ${session.id}.`,`Saved to ${out}. Use it with: openmausbot ${scope==="admin"?"doctor":"bots"} --url ${client.baseUrl} --token-file ${out}`,`Revoke it with: openmausbot token revoke ${session.id}`]}}async function list4(ctx){
|
|
8485
8489
|
let found=(await tokens(ctx)).map(session=>({id:session.id,name:session.label,scope:scopeOf(session),createdAt:session.createdAt,lastSeenAt:session.lastSeenAt,expiresAt:session.expiresAt}));return{result:{tokens:found},exitCode:EXIT.done,human:found.length?found.map(token=>`${token.name} \xB7 ${token.scope} \xB7 until ${day(token.expiresAt)} \xB7 last used ${day(token.lastSeenAt)} \xB7 id ${token.id}`):["No access tokens. Make one with: openmausbot token create NAME --out FILE"]}}async function revoke(ctx){
|
|
@@ -8554,7 +8558,7 @@ limixbot doctor --host [--data-dir DIR] [--port 8799] [--domain HOST]
|
|
|
8554
8558
|
Then: --url URL --token-file FILE. It is listed with openmausbot sessions too.`,"token list":`openmausbot token list
|
|
8555
8559
|
The access tokens, their scope, when each ends and when it was last used (never the token).`,"token revoke":`openmausbot token revoke ID
|
|
8556
8560
|
End an access token at once (openmausbot token list shows the ids).`},VERBS2={doctor,bots:list3,channels:list3,models:list3,messages,send,"send-channel":send,run:runVerb,wait:waitVerb,interrupt,"new-bot":newBot,"new-channel":newChannel,"set-model":setModel,edit,export:exportVerb,events:eventsVerb,"team apply":teamApplyVerb,"team export":teamExportVerb,"engine set":engineVerb,"engine list":engineVerb,connect:connectVerb,"token create":tokenVerb,"token list":tokenVerb,"token revoke":tokenVerb};STOPS_WAITING_ON_CTRL_C=
|
|
8557
|
-
new Set(["run","wait","events"])}});import{spawn as spawn11}from"node:child_process";import{randomBytes as randomBytes11}from"node:crypto";import{closeSync as closeSync16,existsSync as
|
|
8561
|
+
new Set(["run","wait","events"])}});import{spawn as spawn11}from"node:child_process";import{randomBytes as randomBytes11}from"node:crypto";import{closeSync as closeSync16,existsSync as existsSync44,mkdirSync as mkdirSync43,openSync as openSync15,readFileSync as readFileSync65}from"node:fs";import{homedir as homedir33}from"node:os";import{dirname as dirname40,join as join105,resolve as resolve34}from"node:path";import{createInterface as createInterface2}from"node:readline/promises";import{fileURLToPath as fileURLToPath3}from"node:url";var B64U_FIELD=/^[A-Za-z0-9_-]+$/,RELAY_HOST=/^relay[1-9][0-9]?\.openmausbot\.com$/;function encodePairingE2E(descriptor){if(!descriptor||descriptor.v!==1||typeof descriptor.k!="string"||descriptor.k.length!==87||!B64U_FIELD.test(descriptor.k))return null;let relay=typeof descriptor.h=="string"&&Array.isArray(descriptor.r)&&descriptor.r.length>=1&&descriptor.r.length<=4&&descriptor.h.length===22&&B64U_FIELD.test(descriptor.h)&&descriptor.r.every(node3=>RELAY_HOST.test(node3))?{h:descriptor.h,r:descriptor.
|
|
8558
8562
|
r}:{},json3=JSON.stringify({v:1,k:descriptor.k,...relay}),encoded=btoa(json3).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"");return encoded.length<=1024?encoded:null}var MAX_PAIRING_HOSTS=8,ENDPOINT_KINDS=new Set(["hosted","tailnet","lan","bonjour"]);function qrEndpoints(endpoints){let seen=new Set,valid=[];for(let endpoint of endpoints??[])if(!(!endpoint||!ENDPOINT_KINDS.has(endpoint.kind)||!Number.isInteger(endpoint.priority)||endpoint.priority<0||endpoint.priority>1e6))try{let parsed=new URL(
|
|
8559
8563
|
endpoint.url),expectedProtocol=endpoint.kind==="hosted"?"https:":"http:",explicitPort=parsed.port?Number(parsed.port):null,hostname6=parsed.hostname.toLowerCase().replace(/\.$/,"");if(parsed.protocol!==expectedProtocol||hostname6.split(".").includes("")||endpoint.kind==="tailnet"&&!hostname6.endsWith(".ts.net")||explicitPort!==null&&(!Number.isInteger(explicitPort)||explicitPort<1||explicitPort>65535)||parsed.username||parsed.password||parsed.pathname!=="/"||parsed.search||parsed.hash||seen.has(
|
|
8560
8564
|
parsed.origin))continue;seen.add(parsed.origin),valid.push({url:parsed.origin,kind:endpoint.kind,priority:endpoint.priority})}catch{}return valid.sort((left,right)=>left.priority-right.priority).slice(0,MAX_PAIRING_HOSTS)}function encodeEndpoints(endpoints){let bytes2=new TextEncoder().encode(JSON.stringify(endpoints)),binary2="";for(let byte of bytes2)binary2+=String.fromCharCode(byte);return btoa(binary2).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"")}function validSecretPublicKey(value){
|
|
@@ -8596,7 +8600,7 @@ value.trim()===value&&!/[\0\r\n\t ]/.test(value)}function normalizeManagedCompan
|
|
|
8596
8600
|
credentials)}function withManagedCompanionTunnelAccess(credentials,provision){let endpoint=normalizeManagedCompanionEndpoint(provision?.endpoint?.url),token=provision?.connectorToken;if(!endpoint||!validConnectorToken(token))throw new Error("The companion service returned an invalid managed endpoint");let next={...credentials,[MANAGED_COMPANION_ENDPOINT_FIELD]:endpoint,[MANAGED_COMPANION_TOKEN_FIELD]:token,[MANAGED_COMPANION_ORIGIN_VERSION_FIELD]:MANAGED_COMPANION_ORIGIN_VERSION};return delete next[MANAGED_COMPANION_RELEASE_AT_FIELD],
|
|
8597
8601
|
next}function withoutManagedCompanionTunnelAccess(credentials){let next={...credentials};return delete next[MANAGED_COMPANION_ENDPOINT_FIELD],delete next[MANAGED_COMPANION_TOKEN_FIELD],delete next[MANAGED_COMPANION_ORIGIN_VERSION_FIELD],delete next[MANAGED_COMPANION_RELEASE_AT_FIELD],next}function stagedCloudflaredPath({appPath,platform=process.platform,arch:arch2=process.arch}={}){let executable=platform==="win32"?"cloudflared.exe":"cloudflared";return path2.join(String(appPath??""),"dist-nativ\
|
|
8598
8602
|
e","cloudflared",`${platform}-${arch2}`,executable)}function resolveCloudflaredBinary({isPackaged,resourcesPath,appPath,platform=process.platform,arch:arch2=process.arch,environment=process.env,exists=fs2.existsSync}={}){let executable=platform==="win32"?"cloudflared.exe":"cloudflared",bundled=path2.join(String(resourcesPath??""),"cloudflared",executable);if(isPackaged)return exists(bundled)?bundled:null;let override=environment.OMB_CLOUDFLARED_PATH?.trim();if(override)return path2.isAbsolute(override)&&
|
|
8599
|
-
exists(override)?override:null;let staged=stagedCloudflaredPath({appPath,platform,arch:arch2});if(exists(staged))return staged;let pathValue=Object.entries(environment).find(([name])=>name.toLowerCase()==="path")?.[1];if(!pathValue)return null;let
|
|
8603
|
+
exists(override)?override:null;let staged=stagedCloudflaredPath({appPath,platform,arch:arch2});if(exists(staged))return staged;let pathValue=Object.entries(environment).find(([name])=>name.toLowerCase()==="path")?.[1];if(!pathValue)return null;let delimiter11=platform==="win32"?";":":";for(let directory of pathValue.split(delimiter11)){if(!directory||!path2.isAbsolute(directory))continue;let candidate=path2.join(directory,executable);if(exists(candidate))return candidate}return null}function ensurePrivateDirectory(directory,fileSystem,currentUid){fileSystem.mkdirSync(directory,{recursive:!0,mode:448});let stat9=fileSystem.lstatSync(directory);if(!stat9.isDirectory()||stat9.isSymbolicLink())throw new Error("The managed companion runtime path is unsafe");if(currentUid!==void 0&&stat9.uid!==currentUid)throw new Error("The managed companion runtime path has an unexpected owner");fileSystem.chmodSync(directory,448)}function processIsAlive(pid){try{return process.kill(pid,0),!0}catch(error62){
|
|
8600
8604
|
return error62?.code!=="ESRCH"}}var currentUserId2=()=>process.platform==="win32"?void 0:process.getuid?.()??os2.userInfo().uid;function cleanupStaleManagedCompanionTokens(runtimeRoot2,{fileSystem=fs2,currentUid=currentUserId2(),isProcessAlive=processIsAlive}={}){let entries2;try{ensurePrivateDirectory(runtimeRoot2,fileSystem,currentUid),entries2=fileSystem.readdirSync(runtimeRoot2,{withFileTypes:!0})}catch{return 0}let removed=0;for(let entry of entries2){let match=TOKEN_FILE_PATTERN.exec(entry.
|
|
8601
8605
|
name);if(!match||!entry.isFile()||entry.isSymbolicLink())continue;let ownerPid=Number(match[1]);if(!Number.isSafeInteger(ownerPid)||isProcessAlive(ownerPid))continue;let file2=path2.join(runtimeRoot2,entry.name);try{let stat9=fileSystem.lstatSync(file2);if(!stat9.isFile()||stat9.isSymbolicLink()||currentUid!==void 0&&stat9.uid!==currentUid||process.platform!=="win32"&&(stat9.mode&63)!==0)continue;fileSystem.unlinkSync(file2),removed+=1}catch{}}return removed}function writePrivateToken(runtimeRoot2,token,{
|
|
8602
8606
|
fileSystem,processId,identifier,currentUid}){ensurePrivateDirectory(runtimeRoot2,fileSystem,currentUid);let file2=path2.join(runtimeRoot2,`connector-${processId}-${identifier()}.token`),descriptor;try{return descriptor=fileSystem.openSync(file2,"wx",384),fileSystem.writeFileSync(descriptor,token,"utf8"),fileSystem.fsyncSync(descriptor),fileSystem.closeSync(descriptor),descriptor=void 0,fileSystem.chmodSync(file2,384),file2}catch(error62){if(descriptor!==void 0)try{fileSystem.closeSync(descriptor)}catch{}
|
|
@@ -9053,7 +9057,7 @@ here,"..","electron","managed-companion-guardian-main.mjs");return existsSync10(
|
|
|
9053
9057
|
env.OMB_TUNNEL_ORIGIN_PORT||MANAGED_COMPANION_ORIGIN_PORT),current={status:"stopped",ready:!1},tunnel=createManagedCompanionTunnel({binaryPath:options2.binaryPath,guardianEntry:options2.guardian,runtimeRoot:join17(options2.dataDir,TUNNEL_RUNTIME_DIR),originPort,environment:env,fetchImpl:options2.fetchImpl,onChange:state=>{current=state,options2.onState?.(state)}}),started=tunnel.start({endpoint:options2.access.endpoint,token:options2.access.token,originTarget:options2.originTarget});return{address:options2.
|
|
9054
9058
|
access.endpoint,state:()=>current,started,restart:access2=>tunnel.start({endpoint:access2.endpoint,token:access2.token,originTarget:options2.originTarget}),stop:async()=>{await tunnel.stop()}}}function describeTunnelState(state,address2){switch(state.status){case"starting":return"tunnel: connecting\u2026";case"ready":return`tunnel: live at ${address2}`;case"retrying":return`tunnel: ${state.error??"not verified yet"} retrying in ${Math.max(1,Math.round((state.retryInMs??0)/1e3))}s`;case"stopped":
|
|
9055
9059
|
return"tunnel: stopped";default:return`tunnel: ${state.error??state.status}`}}var HERE2=dirname40(fileURLToPath3(import.meta.url)),COMMANDS=["setup","start","serve","pair","sessions","devices","status","login","logout","access","service","browser","fleet","help","--help","-h","--version","-v","version"];function parseArgs3(argv,env=process.env){let implicitStart=!argv.length||argv[0].startsWith("--")&&argv[0]!=="--help"&&argv[0]!=="--version",[command="start",...rest]=implicitStart?["start",...argv]:argv;if(!COMMANDS.includes(command))return{error:`unknown command "${command}\
|
|
9056
|
-
"`};let options2={command:command==="--help"||command==="-h"?"help":command==="--version"||command==="-v"?"version":command==="devices"?"sessions":command,port:Number(env.OMB_PORT||8799),dataDir:env.OMB_DATA_DIR||
|
|
9060
|
+
"`};let options2={command:command==="--help"||command==="-h"?"help":command==="--version"||command==="-v"?"version":command==="devices"?"sessions":command,port:Number(env.OMB_PORT||8799),dataDir:env.OMB_DATA_DIR||join105(homedir33(),".limixbot"),tailscale:!1,tunnel:!1,client:!1,pair:!0,withDeps:!1,json:!1,chatOnly:!1};for(let i2=0;i2<rest.length;i2+=1){let arg=rest[i2],value=()=>{let v3=rest[i2+1];if(v3===void 0||v3.startsWith("--"))throw new Error(`${arg} needs a value`);return i2+=1,v3};try{if(arg===
|
|
9057
9061
|
"--port")options2.port=Number(value());else if(arg==="--data-dir")options2.dataDir=resolve34(value());else if(arg==="--label")options2.label=value();else if(arg==="--public-url")options2.publicUrl=value().replace(/\/+$/,"");else if(arg==="--tailscale")options2.tailscale=!0;else if(arg==="--lan")options2.lan=!0;else if(arg==="--domain"){let domain2=normalizeDomainOption(value());if(typeof domain2!="string")return domain2;options2.domain=domain2}else if(arg==="--tunnel"||arg==="--relay")options2[arg===
|
|
9058
9062
|
"--tunnel"?"tunnel":"relay"]=!0;else if(arg==="--client"||options2.command==="pair"&&arg==="--chat-only")options2.client=!0;else if(arg==="--phone"){let kind=rest[i2+1]?.toLowerCase();if(kind==="ios"||kind==="android")options2.phone=kind,i2+=1;else if(options2.command==="pair")options2.phone="ios";else return{error:"--phone takes ios or android"}}else if(options2.command==="pair"&&arg==="--ttl")options2.pairTtlMs=parseDuration(value(),"--ttl",{min:6e4});else if(arg==="--help"||arg==="-h")options2.
|
|
9059
9063
|
command="help";else if(arg==="--no-pair")options2.pair=!1;else if(arg==="--no-open")options2.open=!1;else if(arg==="--local")options2.local=!0;else if(arg==="--json")options2.json=!0;else if(arg==="--email")options2.email=value();else if(options2.command==="sessions"&&(arg==="revoke"||arg==="list"))arg==="revoke"&&(options2.revoke=value());else if(options2.command==="access"&&!options2.accessAction&&(arg==="list"||arg==="add"||arg==="remove"))options2.accessAction=arg,arg!=="list"&&(options2.email=
|
|
@@ -9066,10 +9070,10 @@ publicUrl):null;if(publicUrlRefusal)return{error:publicUrlRefusal};if(options2.t
|
|
|
9066
9070
|
return{error:"service needs one of: install [the same options as serve], uninstall"};if(options2.domain&&(options2.tailscale||options2.tunnel||options2.publicUrl))return{error:"--domain already gives the server its address; drop --tailscale, --tunnel and --public-url"};if(options2.local&&(options2.tailscale||options2.tunnel||options2.publicUrl||options2.lan||options2.relay))return{error:"--local cannot be combined with a remote-access option"};if(options2.command==="browser"&&!options2.browserAction)
|
|
9067
9071
|
return{error:"browser needs an action: install or status"};if(options2.command==="fleet"){if(!options2.fleetAction)return{error:"fleet needs one of: init --domain HOST [--operator USER], create NAME --admin EMAIL, list, users NAME add|remove EMAIL, suspend NAME, resume NAME, delete NAME --yes, upgrade, agent"};if(["create","users","suspend","resume","delete"].includes(options2.fleetAction)&&!options2.slug)return{error:`fleet ${options2.fleetAction} needs a workspace name`};if(options2.fleetAction===
|
|
9068
9072
|
"users"&&!options2.fleetUserAction)return{error:"fleet users needs: NAME add|remove EMAIL [--chat-only]"};if(options2.cap!==void 0&&(!Number.isFinite(options2.cap)||options2.cap<0))return{error:"--cap must be a dollar amount of 0 or more"}}return options2}function defaultIo(){return{log:line3=>console.log(line3),error:line3=>console.error(line3),ask:async question=>{let rl=createInterface2({input:process.stdin,output:process.stdout});try{return await rl.question(question)}finally{rl.close()}}}}function serverVersion2(here=HERE2){
|
|
9069
|
-
try{let parsed=JSON.parse(
|
|
9073
|
+
try{let parsed=JSON.parse(readFileSync65(resolve34(here,"..","package.json"),"utf8")),version2=typeof parsed=="object"&&parsed!==null?Reflect.get(parsed,"version"):void 0;return typeof version2=="string"&&version2?version2:"0.0.0"}catch{return"0.0.0"}}var message4=error62=>error62 instanceof Error?error62.message:String(error62),serveOwnerToken;async function api(port,path3,init={}){let headers={"content-type":"application/json","x-openmausbot-cli":"1",...serveOwnerToken?{"x-openmausbot-cli-owne\
|
|
9070
9074
|
r":serveOwnerToken}:{}},res=await fetch(`http://127.0.0.1:${port}${path3}`,{method:init.method,body:init.body,headers,signal:AbortSignal.timeout(3e3)}),body=await res.json().catch(()=>({}));return{status:res.status,body}}var SERVICE_TRUST_HELP="This server does not treat commands on this computer as its owner (OMB_LOOPBACK_TRUST=service, or a hosted workspace), so it will not pair devices or list sessions for them. Sign in as an admin and use Settings \u2192 Remote access, let people sign in with the\
|
|
9071
9075
|
ir email (openmausbot access add you@example.com), or restart the server with OMB_LOOPBACK_TRUST=owner.";function refusedAsService(status2,body){return status2===403&&typeof body?.error=="string"&&/shared server|Sign in through the workspace portal/.test(body.error)}async function serverUp(port,pid){try{let{status:status2,body}=await api(port,"/api/health");return status2===200&&body?.app==="openmausbot"&&(pid===void 0||body.pid===pid)}catch{return!1}}async function isWorkspaceRunning(options2){
|
|
9072
|
-
try{let{status:status2,body}=await api(options2.port,"/api/health");if(status2!==200||body?.app!=="openmausbot")return!1;let expected=
|
|
9076
|
+
try{let{status:status2,body}=await api(options2.port,"/api/health");if(status2!==200||body?.app!=="openmausbot")return!1;let expected=readFileSync65(join105(options2.dataDir,"environment-id"),"utf8").trim(),descriptor=await api(options2.port,"/.well-known/openmausbot/environment");return/^[0-9a-f-]{36}$/i.test(expected)&&descriptor.status===200&&descriptor.body?.environmentId===expected}catch{return!1}}async function openDashboard(port,env=process.env){if(env.SSH_CONNECTION||env.SSH_TTY||process.
|
|
9073
9077
|
platform==="linux"&&!env.DISPLAY&&!env.WAYLAND_DISPLAY)return!1;let url3=`http://127.0.0.1:${port}`,command=process.platform==="darwin"?"open":process.platform==="win32"?"rundll32.exe":"xdg-open",args=process.platform==="win32"?["url.dll,FileProtocolHandler",url3]:[url3];return new Promise(done=>{let child=spawn11(command,args,{stdio:"ignore",windowsHide:!0}),timer2=setTimeout(()=>{child.kill(),done(!1)},3e3);child.once("error",()=>{clearTimeout(timer2),done(!1)}),child.once("exit",code=>{clearTimeout(
|
|
9074
9078
|
timer2),done(code===0)})})}var answersAsMausBot=async origin=>typeof(await fetch(`${origin}/.well-known/openmausbot/environment`,{signal:AbortSignal.timeout(3e3)}).then(r2=>r2.json()).catch(()=>null))?.environmentId=="string";async function verifyPhoneEndpoint(port,origin){return!!normalizePhoneOrigin(origin)&&(await checkReach(port,origin)).ok}function applyStartupPreferences(options2,saved){if(options2.local)return{...options2,tunnel:!1,tailscale:!1,publicUrl:void 0,phone:void 0};if(!saved||options2.
|
|
9075
9079
|
tunnel||options2.tailscale||options2.publicUrl)return options2;if(options2.relay&&saved.access==="tunnel")throw new Error(RELAY_NOT_WITH_TUNNEL);if(saved.access==="public-url"&&(!saved.publicUrl||!normalizePhoneOrigin(saved.publicUrl)))throw new Error(`The saved phone address is not a valid HTTPS origin. Run ${cliCommand("setup")} to correct it, or ${cliCommand("--local")} to start only on this computer.`);return{...options2,tunnel:saved.access==="tunnel",tailscale:saved.access==="tailscale",publicUrl:saved.
|
|
@@ -9087,9 +9091,9 @@ ut and its stream is closed`),0)}let{status:status2,body}=await api(options2.por
|
|
|
9087
9091
|
|
|
9088
9092
|
Local 127.0.0.1:${options2.port}`);let address2=await api(options2.port,"/api/auth/pairing").then(r2=>typeof r2.body?.publicUrl=="string"?r2.body.publicUrl:null).catch(()=>null);if(!address2||isLoopbackHost(new URL(address2).hostname))io2.log(` Address none: reachable from this machine only. Ways in: ${cliCommand("serve --help")}`);else for(let line3 of reachLines(address2.startsWith("http:")?"lan":"public-url",address2,options2.port,cliPrefix(),address2.startsWith("http:")?void 0:
|
|
9089
9093
|
await checkReach(options2.port,address2)))io2.log(` ${line3.replace(/^Reach /,"Address ")}`);let sessions=await api(options2.port,"/api/auth/sessions").catch(()=>null);Array.isArray(sessions?.body?.sessions)&&io2.log(`Paired ${sessions.body.sessions.length} device${sessions.body.sessions.length===1?"":"s"} ${cliCommand("devices")}`)}let account2=options2.json?null:describeTunnelAccount(createTunnelAccount({dataDir:options2.dataDir,version:serverVersion2()}).credentials.read());return!options2.
|
|
9090
|
-
json&&fleetCredential()?io2.log(`Limix Bot web address: managed by the fleet (${FLEET_CREDENTIAL_ENV} is set)`):account2?.address&&io2.log(`Limix Bot web address: ${account2.address} (signed in as ${account2.email??"?"}; serve it with ${cliCommand("serve --tunnel")})`),body?0:1}async function runAccess(options2,io2=defaultIo()){let file2=
|
|
9094
|
+
json&&fleetCredential()?io2.log(`Limix Bot web address: managed by the fleet (${FLEET_CREDENTIAL_ENV} is set)`):account2?.address&&io2.log(`Limix Bot web address: ${account2.address} (signed in as ${account2.email??"?"}; serve it with ${cliCommand("serve --tunnel")})`),body?0:1}async function runAccess(options2,io2=defaultIo()){let file2=join105(options2.dataDir,"config.json"),raw={};if(existsSync44(file2))try{let parsed=JSON.parse(readFileSync65(file2,"utf8"));if(typeof parsed!="object"||parsed===
|
|
9091
9095
|
null||Array.isArray(parsed))throw new Error("not an object");raw=Object.fromEntries(Object.entries(parsed))}catch(error62){return io2.error(`${file2} could not be read (${message4(error62)}); fix it before changing who can sign in`),1}let current=typeof raw.signIn=="object"&&raw.signIn!==null?Object(raw.signIn):{},list5=value=>parseAllowList(Array.isArray(value)?value.map(String).join(","):""),admins=list5(Reflect.get(current,"admins")),members2=list5(Reflect.get(current,"members")),overridden=Object.
|
|
9092
|
-
keys(signInFromEnv()).length>0,write=async next=>{if(
|
|
9096
|
+
keys(signInFromEnv()).length>0,write=async next=>{if(mkdirSync43(options2.dataDir,{recursive:!0,mode:448}),writeFileAtomic(file2,`${JSON.stringify({...raw,signIn:next},null,2)}
|
|
9093
9097
|
`,{mode:384}),!sharedSignIn({admins,members:members2})&&!sharedSignIn(next)&&!hostedWorkspaceConfigured())return;let decisions=raw.decisions&&typeof raw.decisions=="object"?raw.decisions.retentionDays:void 0;bindDecisionRetention(()=>decisionRetentionDays(typeof decisions=="number"?decisions:void 0));let changed2=["admins","members"].filter(key2=>next[key2].join(",")!==(key2==="admins"?admins:members2).join(","));appendAdminAction(options2.dataDir,{category:"people",action:"people.update",target:{
|
|
9094
9098
|
kind:"settings"},actor:{kind:"cli"},changed:changed2.map(key2=>`signIn.${key2}`),before:Object.fromEntries(changed2.map(key2=>[`signIn.${key2}`,key2==="admins"?admins:members2])),after:Object.fromEntries(changed2.map(key2=>[`signIn.${key2}`,next[key2]]))}),await flushAdminActivity(options2.dataDir)};if(options2.accessAction==="list"){if(!admins.length&&!members2.length)return io2.log("nobody can sign in with an email yet; pairing codes only. Add someone with: openmausbot access add you@example.c\
|
|
9095
9099
|
om"),0;for(let entry2 of admins)io2.log(`${entry2.padEnd(40)} full access`);for(let entry2 of members2)io2.log(`${entry2.padEnd(40)} chat and approvals`);return overridden&&io2.log("(OMB_SIGNIN_EMAILS / OMB_SIGNIN_MEMBER_EMAILS are set in the environment and win over this list while the server runs)"),0}let entry=(options2.email??"").trim().toLowerCase();if(!entry||!entry.startsWith("@")&&!entry.includes("@")||/\s/.test(entry))return io2.error("give an email address, or @domain for everyone at t\
|
|
@@ -9103,8 +9107,8 @@ n-out failed: ${message4(error62)}`),1}return describeTunnelAccount(account2.cre
|
|
|
9103
9107
|
status2=browserEngineStatus2({dataDir:options2.dataDir});if(options2.browserAction==="status")return io2.log(describeBrowserEngine2(status2,status2.kind==="ready"?new(await Promise.resolve().then(()=>(init_launcher(),launcher_exports))).ChromeLauncher({dataDir:options2.dataDir}).describe():void 0)),status2.kind!=="ready"&&status2.installable&&io2.log("install it with: limixbot browser install"),status2.kind==="ready"?0:1;let binary2=resolveAgentBrowserBinary2({dataDir:options2.dataDir});if(binary2)
|
|
9104
9108
|
io2.log(`agent-browser is already here: ${binary2}`);else{if(status2.kind!=="ready"&&!status2.installable)return io2.error(status2.reason),1;try{binary2=await installAgentBrowserBinary2({dataDir:options2.dataDir,log:io2.log})}catch(error62){return io2.error(`could not install agent-browser: ${message4(error62)}`),1}io2.log(`installed ${binary2}`)}try{await ensureChrome2(binary2,{withDeps:options2.withDeps===!0,log:io2.log})}catch(error62){return io2.error(`Chrome is not ready: ${message4(error62)}`),
|
|
9105
9109
|
process.platform==="linux"&&!options2.withDeps&&io2.error(`on Linux, install Chrome's system libraries with: sudo ${cliCommand("browser install --with-deps")}, then retry ${cliCommand("browser install")} as the user running serve`),1}return io2.log("browser installed for this user and data directory; run serve as the same user, then enable it under Settings \u2192 Computers and per bot"),process.platform==="linux"&&options2.withDeps&&io2.log(`if serve runs as another user, run ${cliCommand("brow\
|
|
9106
|
-
ser install")} from that user's login shell too`),0}function serverEntry(here=HERE2){let bundled=
|
|
9107
|
-
|
|
9110
|
+
ser install")} from that user's login shell too`),0}function serverEntry(here=HERE2){let bundled=join105(here,"index.js"),root=resolve34(here,"..");if(existsSync44(bundled)){let staticDir2=[join105(root,"dist"),join105(here,"..","ui")].find(d=>existsSync44(join105(d,"index.html")))??null,skillsDir=existsSync44(join105(root,"skills"))?join105(root,"skills"):null;return{command:process.execPath,args:[bundled],staticDir:staticDir2,skillsDir}}let source=join105(here,"index.ts"),staticDir=existsSync44(
|
|
9111
|
+
join105(root,"dist","index.html"))?join105(root,"dist"):null;return{command:process.execPath,args:["--experimental-strip-types",source],staticDir,skillsDir:existsSync44(join105(root,"skills"))?join105(root,"skills"):null}}async function planTunnel(options2,log2,recovery){let access2=null,account2=null,fail3=error62=>(account2?.service.dispose(),{error:error62}),credential=fleetCredential();if(credential){log2(`tunnel: using the installation credential from ${FLEET_CREDENTIAL_ENV}`);try{access2=await fleetAccess(
|
|
9108
9112
|
{credential,version:serverVersion2()})}catch(error62){return{error:`--tunnel: ${message4(error62)}`}}}else{if(account2=createTunnelAccount({dataDir:options2.dataDir,version:serverVersion2(),recovery,log:line3=>log2(`tunnel: ${line3}`)}),account2.credentials.status==="unavailable")return fail3(`${account2.credentials.file} exists but could not be read; fix or remove it`);if(!describeTunnelAccount(account2.credentials.read()).email)return fail3(`no account on this machine yet: run ${cliCommand("lo\
|
|
9109
9113
|
gin")} first, then ${cliCommand("serve --tunnel")}`);try{let state=await account2.service.retry(),saved=tunnelAccess(account2.credentials.read())!==null;state.status==="signed-out"?log2(`tunnel: the sign-in on this machine expired; run ${cliCommand("login")} to renew it${saved?" (serving the saved address until then)":""}`):state.message&&log2(`tunnel: ${state.message}${saved?" Serving the saved address for now.":""}`)}catch(error62){log2(`tunnel: control plane not reachable right now (${message4(
|
|
9110
9114
|
error62)}); using the saved address`)}if(access2=tunnelAccess(account2.credentials.read()),!access2)return fail3(`this machine has no public address; run ${cliCommand("login")} again`)}let binary2;try{binary2=await ensureCloudflared({dataDir:options2.dataDir,log:log2})}catch(error62){return fail3(`--tunnel: ${message4(error62)}`)}let guardian=guardianEntry();return guardian?{access:access2,binary:binary2,guardian,origin:createTunnelOrigin(),account:account2}:fail3("--tunnel: the connector guardi\
|
|
@@ -9113,7 +9117,7 @@ envPublicUrl(process.env,log2)),tailscale=null;if(await clearLeftoverTailscaleSe
|
|
|
9113
9117
|
tunnel});if("error"in planned)return console.error(planned.error),1;plan=planned,publicUrl&&publicUrl!==plan.access.endpoint&&log2(`note: --public-url is ignored with --tunnel; the address is ${plan.access.endpoint}`),publicUrl=plan.access.endpoint}let caddyBinary=null;if(options2.domain){try{caddyBinary=await ensureCaddy({dataDir:options2.dataDir,log:log2})}catch(error62){return console.error(`--domain: ${message4(error62)}`),1}publicUrl=`https://${options2.domain}`}let entry=serverEntry();entry.
|
|
9114
9118
|
staticDir||log2("note: no built UI found next to the server; the API runs but browsers get no page (build with `pnpm exec vite build`)");let env={...process.env,OMB_DATA_DIR:options2.dataDir,OMB_PORT:String(options2.port),OMB_WEBHOOK_PORT:process.env.OMB_WEBHOOK_PORT||String(options2.port+1),...options2.relay?{OMB_PHONE_RELAY:"1"}:{}};options2.local&&delete env.OMB_PUBLIC_URL;let serviceTrust=resolveLoopbackTrust({env,desktopManaged:!1,hostedWorkspace:hostedWorkspaceConfigured(env)}).trust==="se\
|
|
9115
9119
|
rvice",ownerToken=serviceTrust?randomBytes11(32).toString("base64url"):void 0;ownerToken?env.OMB_CLI_OWNER_STDIN="1":delete env.OMB_CLI_OWNER_STDIN,entry.staticDir&&(env.OMB_STATIC_DIR=entry.staticDir),entry.skillsDir&&!process.env.OMB_SKILLS_DIR&&(env.OMB_SKILLS_DIR=entry.skillsDir),options2.label&&!process.env.OMB_ENVIRONMENT_LABEL&&(env.OMB_ENVIRONMENT_LABEL=options2.label),plan&&Object.assign(env,{OMB_TUNNEL_SOCKET:plan.origin.socketPath,OMB_SERVES_TUNNEL:"1"});let lanRefusal=options2.lan?lanProblem():
|
|
9116
|
-
null;lanRefusal&&log2(lanRefusal),options2.lan&&!lanRefusal?env.OMB_LAN="1":delete env.OMB_LAN;let logPath,logFd,tailscaleShare=null,startupCancelled=!1,cancelStartup=()=>{startupCancelled=!0};process.on("SIGINT",cancelStartup),process.on("SIGTERM",cancelStartup);let child;try{if(options2.guided){let logsDir=
|
|
9120
|
+
null;lanRefusal&&log2(lanRefusal),options2.lan&&!lanRefusal?env.OMB_LAN="1":delete env.OMB_LAN;let logPath,logFd,tailscaleShare=null,startupCancelled=!1,cancelStartup=()=>{startupCancelled=!0};process.on("SIGINT",cancelStartup),process.on("SIGTERM",cancelStartup);let child;try{if(options2.guided){let logsDir=join105(options2.dataDir,"logs");mkdirSync43(logsDir,{recursive:!0,mode:448}),logPath=join105(logsDir,`server-${Date.now()}-${process.pid}.log`),logFd=openSync15(logPath,"wx",384),log2(`
|
|
9117
9121
|
Starting your workspace\u2026`)}if(tailscale){let served=await tailscaleServe(tailscale,options2.port,{dataDir:options2.dataDir,otherServer:answersAsMausBot}),listening="failure"in served?tailnetListenFallback(served.failure,tailscale,options2.port):null;if(tailscaleShare="failure"in served?listening&&{origin:listening.origin,stop:async()=>{}}:served,startupCancelled||!tailscaleShare)throw startupCancelled?new SetupCancelled:new Error(`--tailscale: ${explainTailscaleFailure("failure"in served?served.
|
|
9118
9122
|
failure:"unknown")}`);Object.assign(env,listening?.env),publicUrl=tailscaleShare.origin,log2(listening?.line??`tailscale: serving https://${tailscale.dnsName} \u2192 http://127.0.0.1:${options2.port} (only your tailnet can reach it)`)}if(startupCancelled)throw new SetupCancelled;publicUrl&&(env.OMB_PUBLIC_URL=publicUrl),child=spawn11(entry.command,entry.args,{env,stdio:[ownerToken?"pipe":"ignore",logFd??"inherit",logFd??"inherit"]}),ownerToken&&(child.stdin?.on("error",()=>{}),child.stdin?.end(`${ownerToken}\
|
|
9119
9123
|
|
|
@@ -9136,7 +9140,7 @@ interactive&&options2.open!==!1&&await(flow3.open??openDashboard)(options2.port)
|
|
|
9136
9140
|
or start unattended with ${cliCommand("serve")}.`),1;if(!await runSetup2({dataDir:options2.dataDir,port:options2.port}))return io2.log(`Setup cancelled. Run ${cliPrefix()} when you're ready.`),130}let saved=readCliStartup2(options2.dataDir),launch=options2.command==="setup"?options2:applyStartupPreferences(options2,saved);if(interactive&&options2.pair&&!options2.local&&(options2.command==="setup"||!saved)){io2.log(`
|
|
9137
9141
|
One optional step: connect your phone. You can skip this and start chatting here.`);let result2=await(flow3.phoneSetup??runPhoneSetup)(launch,prompts,{accountReady:value=>!!describeTunnelAccount(createTunnelAccount({dataDir:value.dataDir,version:serverVersion2()}).credentials.read()).email,login:(value,ui2)=>runLogin(value,{log:ui2.log,error:ui2.log,ask:question=>/code/i.test(question)?ui2.secret(question):ui2.ask(question)})});launch={...result2.options,phone:result2.phone},saveCliStartup2(options2.
|
|
9138
9142
|
dataDir,startupPreferences(launch))}return options2.command==="setup"?(io2.log(`
|
|
9139
|
-
All set. Start with: ${cliPrefix()}`),(options2.dataDir!==
|
|
9143
|
+
All set. Start with: ${cliPrefix()}`),(options2.dataDir!==join105(homedir33(),".limixbot")||options2.port!==8799)&&io2.log(`Use the same --data-dir (${options2.dataDir}) and --port (${options2.port}) options when starting.`),0):(saved&&io2.log(`
|
|
9140
9144
|
Welcome back. Using your saved AI connection.`),startServer({...launch,guided:interactive}))}catch(error62){if(!(error62 instanceof SetupCancelled))throw error62;return io2.log(`
|
|
9141
9145
|
Setup stopped. Any AI setup already saved is kept; no server was started. Run ${cliCommand("setup")} to continue.`),130}}async function main(argv=process.argv.slice(2)){if(argv[0]==="sentinel")return runSentinelCli(argv.slice(1));if(HEADLESS_VERBS.has(argv[0]??"")||argv[0]==="help"&&HEADLESS_VERBS.has(argv[1]??""))return(await Promise.resolve().then(()=>(init_main2(),main_exports))).runHeadless(argv);let options2=parseArgs3(argv);if("error"in options2)return console.error(`${options2.error}
|
|
9142
9146
|
All commands and options: ${cliCommand("--help")}`),2;switch(process.env.OMB_DATA_DIR=options2.dataDir,options2.command){case"setup":case"start":return runOnboardingCommand(options2);case"serve":return serveUntilStopped(options2);case"pair":return runPair(options2);case"sessions":return runSessions(options2);case"status":return runStatus(options2);case"login":return runLogin(options2);case"access":return runAccess(options2);case"service":return runServiceCommand({action:options2.serviceAction??"\
|