@iaforged/context-code 2.4.4 → 2.4.7

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.
@@ -1 +1 @@
1
- import{feature as e}from"../../recovery/bunBundleShim.js";import{createRequire as r}from"module";const s=r(import.meta.url);import{chmod as o,open as t,rename as n,stat as i,unlink as c}from"fs/promises";import a from"lodash-es/mapValues.js";import p from"lodash-es/memoize.js";import{dirname as l,join as f,parse as u}from"path";import{getPlatform as d}from"../../utils/platform.js";import{getPluginErrorMessage as m}from"../../types/plugin.js";import{isClaudeInChromeMCPServer as g}from"../../utils/claudeInChrome/common.js";import{getCurrentProjectConfig as v,getGlobalConfig as M,saveCurrentProjectConfig as S,saveGlobalConfig as h}from"../../utils/config.js";import{getCwd as w}from"../../utils/cwd.js";import{logForDebugging as C}from"../../utils/debug.js";import{getErrnoCode as y}from"../../utils/errors.js";import{getFsImplementation as j}from"../../utils/fsOperations.js";import{safeParseJSON as P}from"../../utils/json.js";import{logError as b}from"../../utils/log.js";import{getPluginMcpServers as x}from"../../utils/plugins/mcpPluginIntegration.js";import{loadAllPluginsCacheOnly as $}from"../../utils/plugins/pluginLoader.js";import{isSettingSourceEnabled as E}from"../../utils/settings/constants.js";import{getManagedFilePath as O}from"../../utils/settings/managedPath.js";import{isRestrictedToPluginOnly as F}from"../../utils/settings/pluginOnlyPolicy.js";import{getInitialSettings as A,getSettingsForSource as B}from"../../utils/settings/settings.js";import{isMcpServerCommandEntry as N,isMcpServerNameEntry as D,isMcpServerUrlEntry as k}from"../../utils/settings/types.js";import{jsonStringify as V}from"../../utils/slowOperations.js";import{logEvent as U}from"../analytics/index.js";import{fetchClaudeAIMcpConfigsIfEligible as _}from"./claudeai.js";import{expandEnvVarsInString as T}from"./envExpansion.js";import{McpJsonConfigSchema as W,McpServerConfigSchema as I}from"./types.js";import{getProjectMcpServerStatus as R}from"./utils.js";export function getEnterpriseMcpFilePath(){return f(O(),"managed-mcp.json")}function addScopeToServers(e,r){if(!e)return{};const s={};for(const[o,t]of Object.entries(e))s[o]={...t,scope:r};return s}async function writeMcpjsonFile(e){const r=f(w(),".mcp.json");let s;try{s=(await i(r)).mode}catch(e){if("ENOENT"!==y(e))throw e}const a=`${r}.tmp.${process.pid}.${Date.now()}`,p=await t(a,"w",s??420);try{await p.writeFile(V(e,null,2),{encoding:"utf8"}),await p.datasync()}finally{await p.close()}try{void 0!==s&&await o(a,s),await n(a,r)}catch(e){try{await c(a)}catch{}throw e}}function getServerCommandArray(e){if(void 0!==e.type&&"stdio"!==e.type)return null;const r=e;return[r.command,...r.args??[]]}function commandArraysMatch(e,r){return e.length===r.length&&e.every((e,s)=>e===r[s])}function getServerUrl(e){return"url"in e?e.url:null}const J=["/v2/session_ingress/shttp/mcp/","/v2/ccr-sessions/"];export function unwrapCcrProxyUrl(e){if(!J.some(r=>e.includes(r)))return e;try{const r=new URL(e);return r.searchParams.get("mcp_url")||e}catch{return e}}export function getMcpServerSignature(e){const r=getServerCommandArray(e);if(r)return`stdio:${V(r)}`;const s=getServerUrl(e);return s?`url:${unwrapCcrProxyUrl(s)}`:null}export function dedupPluginMcpServers(e,r){const s=new Map;for(const[e,o]of Object.entries(r)){const r=getMcpServerSignature(o);r&&!s.has(r)&&s.set(r,e)}const o={},t=[],n=new Map;for(const[r,i]of Object.entries(e)){const e=getMcpServerSignature(i);if(null===e){o[r]=i;continue}const c=s.get(e);if(void 0!==c){C(`Suppressing plugin MCP server "${r}": duplicates manually-configured "${c}"`),t.push({name:r,duplicateOf:c});continue}const a=n.get(e);void 0===a?(n.set(e,r),o[r]=i):(C(`Suppressing plugin MCP server "${r}": duplicates earlier plugin server "${a}"`),t.push({name:r,duplicateOf:a}))}return{servers:o,suppressed:t}}export function dedupClaudeAiMcpServers(e,r){const s=new Map;for(const[e,o]of Object.entries(r)){if(isMcpServerDisabled(e))continue;const r=getMcpServerSignature(o);r&&!s.has(r)&&s.set(r,e)}const o={},t=[];for(const[r,n]of Object.entries(e)){const e=getMcpServerSignature(n),i=null!==e?s.get(e):void 0;void 0===i?o[r]=n:(C(`Suppressing claude.ai connector "${r}": duplicates manually-configured "${i}"`),t.push({name:r,duplicateOf:i}))}return{servers:o,suppressed:t}}function urlMatchesPattern(e,r){const s=function(e){const r=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${r}$`)}(r);return s.test(e)}function isMcpServerDenied(e,r){const s=A();if(!s.deniedMcpServers)return!1;for(const r of s.deniedMcpServers)if(D(r)&&r.serverName===e)return!0;if(r){const e=getServerCommandArray(r);if(e)for(const r of s.deniedMcpServers)if(N(r)&&commandArraysMatch(r.serverCommand,e))return!0;const o=getServerUrl(r);if(o)for(const e of s.deniedMcpServers)if(k(e)&&urlMatchesPattern(o,e.serverUrl))return!0}return!1}function isMcpServerAllowedByPolicy(e,r){if(isMcpServerDenied(e,r))return!1;const s=shouldAllowManagedMcpServersOnly()?B("policySettings")??{}:A();if(!s.allowedMcpServers)return!0;if(0===s.allowedMcpServers.length)return!1;const o=s.allowedMcpServers.some(N),t=s.allowedMcpServers.some(k);if(r){const n=getServerCommandArray(r),i=getServerUrl(r);if(n){if(o){for(const e of s.allowedMcpServers)if(N(e)&&commandArraysMatch(e.serverCommand,n))return!0;return!1}for(const r of s.allowedMcpServers)if(D(r)&&r.serverName===e)return!0;return!1}if(i){if(t){for(const e of s.allowedMcpServers)if(k(e)&&urlMatchesPattern(i,e.serverUrl))return!0;return!1}for(const r of s.allowedMcpServers)if(D(r)&&r.serverName===e)return!0;return!1}for(const r of s.allowedMcpServers)if(D(r)&&r.serverName===e)return!0;return!1}for(const r of s.allowedMcpServers)if(D(r)&&r.serverName===e)return!0;return!1}export function filterMcpServersByPolicy(e){const r={},s=[];for(const[o,t]of Object.entries(e)){const e=t;"sdk"===e.type||isMcpServerAllowedByPolicy(o,e)?r[o]=t:s.push(o)}return{allowed:r,blocked:s}}function expandEnvVars(e){const r=[];function expandString(e){const{expanded:s,missingVars:o}=T(e);return r.push(...o),s}let s;switch(e.type){case void 0:case"stdio":{const r=e;s={...r,command:expandString(r.command),args:r.args.map(expandString),env:r.env?a(r.env,expandString):void 0};break}case"sse":case"http":case"ws":{const r=e;s={...r,url:expandString(r.url),headers:r.headers?a(r.headers,expandString):void 0};break}case"sse-ide":case"ws-ide":case"sdk":case"claudeai-proxy":s=e}return{expanded:s,missingVars:[...new Set(r)]}}export async function addMcpConfig(r,s,o){if(r.match(/[^a-zA-Z0-9_-]/))throw new Error(`Invalid name ${r}. Names can only contain letters, numbers, hyphens, and underscores.`);if(g(r))throw new Error(`Cannot add MCP server "${r}": this name is reserved.`);if(e("CHICAGO_MCP")){const{isComputerUseMCPServer:e}=await import("../../utils/computerUse/common.js");if(e(r))throw new Error(`Cannot add MCP server "${r}": this name is reserved.`)}const{isDatabaseMCPServer:t}=await import("../../utils/databaseMcp/common.js");if(t(r))throw new Error(`Cannot add MCP server "${r}": this name is reserved.`);const{isComputerControlMCPServer:n}=await import("../../utils/computerControlMcp/common.js");if(n(r))throw new Error(`Cannot add MCP server "${r}": this name is reserved.`);if(doesEnterpriseMcpConfigExist())throw new Error("Cannot add MCP server: enterprise MCP configuration is active and has exclusive control over MCP servers");const i=I().safeParse(s);if(!i.success){const e=i.error.issues.map(e=>`${e.path.join(".")}: ${e.message}`).join(", ");throw new Error(`Invalid configuration: ${e}`)}const c=i.data;if(isMcpServerDenied(r,c))throw new Error(`Cannot add MCP server "${r}": server is explicitly blocked by enterprise policy`);if(!isMcpServerAllowedByPolicy(r,c))throw new Error(`Cannot add MCP server "${r}": not allowed by enterprise policy`);switch(o){case"project":{const{servers:e}=getProjectMcpConfigsFromCwd();if(e[r])throw new Error(`MCP server ${r} already exists in .mcp.json`);break}case"user":{const e=M();if(e.mcpServers?.[r])throw new Error(`MCP server ${r} already exists in user config`);break}case"local":{const e=v();if(e.mcpServers?.[r])throw new Error(`MCP server ${r} already exists in local config`);break}case"dynamic":throw new Error("Cannot add MCP server to scope: dynamic");case"enterprise":throw new Error("Cannot add MCP server to scope: enterprise");case"claudeai":throw new Error("Cannot add MCP server to scope: claudeai")}switch(o){case"project":{const{servers:e}=getProjectMcpConfigsFromCwd(),s={};for(const[r,o]of Object.entries(e)){const{scope:e,...t}=o;s[r]=t}s[r]=c;const o={mcpServers:s};try{await writeMcpjsonFile(o)}catch(e){throw new Error(`Failed to write to .mcp.json: ${e}`)}break}case"user":h(e=>({...e,mcpServers:{...e.mcpServers,[r]:c}}));break;case"local":S(e=>({...e,mcpServers:{...e.mcpServers,[r]:c}}));break;default:throw new Error(`Cannot add MCP server to scope: ${o}`)}}export async function removeMcpConfig(e,r){switch(r){case"project":{const{servers:r}=getProjectMcpConfigsFromCwd();if(!r[e])throw new Error(`No MCP server found with name: ${e} in .mcp.json`);const s={};for(const[o,t]of Object.entries(r))if(o!==e){const{scope:e,...r}=t;s[o]=r}const o={mcpServers:s};try{await writeMcpjsonFile(o)}catch(e){throw new Error(`Failed to remove from .mcp.json: ${e}`)}break}case"user":{const r=M();if(!r.mcpServers?.[e])throw new Error(`No user-scoped MCP server found with name: ${e}`);h(r=>{const{[e]:s,...o}=r.mcpServers??{};return{...r,mcpServers:o}});break}case"local":{const r=v();if(!r.mcpServers?.[e])throw new Error(`No project-local MCP server found with name: ${e}`);S(r=>{const{[e]:s,...o}=r.mcpServers??{};return{...r,mcpServers:o}});break}default:throw new Error(`Cannot remove MCP server from scope: ${r}`)}}export function getProjectMcpConfigsFromCwd(){if(!E("projectSettings"))return{servers:{},errors:[]};const e=f(w(),".mcp.json"),{config:r,errors:s}=parseMcpConfigFromFilePath({filePath:e,expandVars:!0,scope:"project"});if(!r){const r=s.filter(e=>!e.message.startsWith("MCP config file not found"));return r.length>0?(C(`MCP config errors for ${e}: ${V(r.map(e=>e.message))}`,{level:"error"}),{servers:{},errors:r}):{servers:{},errors:[]}}return{servers:r.mcpServers?addScopeToServers(r.mcpServers,"project"):{},errors:s||[]}}export function getMcpConfigsByScope(e){const r={project:"projectSettings",user:"userSettings",local:"localSettings"};if(e in r&&!E(r[e]))return{servers:{},errors:[]};switch(e){case"project":{const r={},s=[],o=[];let t=w();for(;t!==u(t).root;)o.push(t),t=l(t);for(const t of o.reverse()){const o=f(t,".mcp.json"),{config:n,errors:i}=parseMcpConfigFromFilePath({filePath:o,expandVars:!0,scope:"project"});if(!n){const e=i.filter(e=>!e.message.startsWith("MCP config file not found"));e.length>0&&(C(`MCP config errors for ${o}: ${V(e.map(e=>e.message))}`,{level:"error"}),s.push(...e));continue}n.mcpServers&&Object.assign(r,addScopeToServers(n.mcpServers,e)),i.length>0&&s.push(...i)}return{servers:r,errors:s}}case"user":{const r=M().mcpServers;if(!r)return{servers:{},errors:[]};const{config:s,errors:o}=parseMcpConfig({configObject:{mcpServers:r},expandVars:!0,scope:"user"});return{servers:addScopeToServers(s?.mcpServers,e),errors:o}}case"local":{const r=v().mcpServers;if(!r)return{servers:{},errors:[]};const{config:s,errors:o}=parseMcpConfig({configObject:{mcpServers:r},expandVars:!0,scope:"local"});return{servers:addScopeToServers(s?.mcpServers,e),errors:o}}case"enterprise":{const r=getEnterpriseMcpFilePath(),{config:s,errors:o}=parseMcpConfigFromFilePath({filePath:r,expandVars:!0,scope:"enterprise"});if(!s){const e=o.filter(e=>!e.message.startsWith("MCP config file not found"));return e.length>0?(C(`Enterprise MCP config errors for ${r}: ${V(e.map(e=>e.message))}`,{level:"error"}),{servers:{},errors:e}):{servers:{},errors:[]}}return{servers:addScopeToServers(s.mcpServers,e),errors:o}}}}export function getMcpConfigByName(e){const{servers:r}=getMcpConfigsByScope("enterprise");if(F("mcp"))return r[e]??null;const{servers:s}=getMcpConfigsByScope("user"),{servers:o}=getMcpConfigsByScope("project"),{servers:t}=getMcpConfigsByScope("local");return r[e]?r[e]:t[e]?t[e]:o[e]?o[e]:s[e]?s[e]:null}export async function getClaudeCodeMcpConfigs(e={},r=Promise.resolve({})){const{servers:s}=getMcpConfigsByScope("enterprise");if(doesEnterpriseMcpConfigExist()){const e={};for(const[r,o]of Object.entries(s))isMcpServerAllowedByPolicy(r,o)&&(e[r]=o);return{servers:e,errors:[]}}const o=F("mcp"),t={servers:{}},{servers:n}=o?t:getMcpConfigsByScope("user"),{servers:i}=o?t:getMcpConfigsByScope("project"),{servers:c}=o?t:getMcpConfigsByScope("local"),a={},p=await $(),l=[];if(p.errors.length>0)for(const e of p.errors)if("mcp-config-invalid"===e.type||"mcpb-download-failed"===e.type||"mcpb-extract-failed"===e.type||"mcpb-invalid-manifest"===e.type){const r=`Plugin MCP loading error - ${e.type}: ${m(e)}`;b(new Error(r))}else{const r=e.type;C(`Plugin not available for MCP: ${e.source} - error type: ${r}`)}const f=await Promise.all(p.enabled.map(e=>x(e,l)));for(const e of f)e&&Object.assign(a,e);if(l.length>0)for(const e of l){const r=`Plugin MCP server error - ${e.type}: ${m(e)}`;b(new Error(r))}const u={};for(const[e,r]of Object.entries(i))"approved"===R(e)&&(u[e]=r);const d=await r,g={};for(const[r,s]of Object.entries({...n,...u,...c,...e,...d}))!isMcpServerDisabled(r)&&isMcpServerAllowedByPolicy(r,s)&&(g[r]=s);const v={},M={};for(const[e,r]of Object.entries(a))isMcpServerDisabled(e)||!isMcpServerAllowedByPolicy(e,r)?M[e]=r:v[e]=r;const{servers:S,suppressed:h}=dedupPluginMcpServers(v,g);Object.assign(S,M);for(const{name:e,duplicateOf:r}of h){const s=e.split(":");"plugin"!==s[0]||s.length<3||l.push({type:"mcp-server-suppressed-duplicate",source:e,plugin:s[1],serverName:s.slice(2).join(":"),duplicateOf:r})}const w=Object.assign({},S,n,u,c),y={};for(const[e,r]of Object.entries(w))isMcpServerAllowedByPolicy(e,r)&&(y[e]=r);return{servers:y,errors:l}}export async function getAllMcpConfigs(){if(doesEnterpriseMcpConfigExist())return getClaudeCodeMcpConfigs();const e=_(),{servers:r,errors:s}=await getClaudeCodeMcpConfigs({},e),{allowed:o}=filterMcpServersByPolicy(await e),{servers:t}=dedupClaudeAiMcpServers(o,r);return{servers:Object.assign({},t,r),errors:s}}export function parseMcpConfig(e){const{configObject:r,expandVars:s,scope:o,filePath:t}=e,n=W().safeParse(r);if(!n.success)return{config:null,errors:n.error.issues.map(e=>({...t&&{file:t},path:e.path.join("."),message:"Does not adhere to MCP server configuration schema",mcpErrorMetadata:{scope:o,severity:"fatal"}}))};const i=[],c={};for(const[e,r]of Object.entries(n.data.mcpServers)){let n=r;if(s){const{expanded:s,missingVars:c}=expandEnvVars(r);c.length>0&&i.push({...t&&{file:t},path:`mcpServers.${e}`,message:`Missing environment variables: ${c.join(", ")}`,suggestion:`Set the following environment variables: ${c.join(", ")}`,mcpErrorMetadata:{scope:o,serverName:e,severity:"warning"}}),n=s}"windows"!==d()||n.type&&"stdio"!==n.type||"npx"!==n.command&&!n.command.endsWith("\\npx")&&!n.command.endsWith("/npx")||i.push({...t&&{file:t},path:`mcpServers.${e}`,message:"Windows requires 'cmd /c' wrapper to execute npx",suggestion:'Change command to "cmd" with args ["/c", "npx", ...]',mcpErrorMetadata:{scope:o,serverName:e,severity:"warning"}}),c[e]=n}return{config:{mcpServers:c},errors:i}}export function parseMcpConfigFromFilePath(e){const{filePath:r,expandVars:s,scope:o}=e,t=j();let n;try{n=t.readFileSync(r,{encoding:"utf8"})}catch(e){return"ENOENT"===y(e)?{config:null,errors:[{file:r,path:"",message:`MCP config file not found: ${r}`,suggestion:"Check that the file path is correct",mcpErrorMetadata:{scope:o,severity:"fatal"}}]}:(C(`MCP config read error for ${r} (scope=${o}): ${e}`,{level:"error"}),{config:null,errors:[{file:r,path:"",message:`Failed to read file: ${e}`,suggestion:"Check file permissions and ensure the file exists",mcpErrorMetadata:{scope:o,severity:"fatal"}}]})}const i=P(n);return i?parseMcpConfig({configObject:i,expandVars:s,scope:o,filePath:r}):(C(`MCP config is not valid JSON: ${r} (scope=${o}, length=${n.length}, first100=${V(n.slice(0,100))})`,{level:"error"}),{config:null,errors:[{file:r,path:"",message:"MCP config is not a valid JSON",suggestion:"Fix the JSON syntax errors in the file",mcpErrorMetadata:{scope:o,severity:"fatal"}}]})}export const doesEnterpriseMcpConfigExist=p(()=>{const{config:e}=parseMcpConfigFromFilePath({filePath:getEnterpriseMcpFilePath(),expandVars:!0,scope:"enterprise"});return null!==e});export function shouldAllowManagedMcpServersOnly(){return!0===B("policySettings")?.allowManagedMcpServersOnly}export function areMcpConfigsAllowedWithEnterpriseMcpConfig(e){return Object.values(e).every(e=>"sdk"===e.type&&"claude-vscode"===e.name)}const z=e("CHICAGO_MCP")?s("../../utils/computerUse/common.js").COMPUTER_USE_MCP_SERVER_NAME:null;function isDefaultDisabledBuiltin(e){return null!==z&&e===z}export function isMcpServerDisabled(e){const r=v();if(isDefaultDisabledBuiltin(e)){return!(r.enabledMcpServers||[]).includes(e)}return(r.disabledMcpServers||[]).includes(e)}function toggleMembership(e,r,s){return e.includes(r)===s?e:s?[...e,r]:e.filter(e=>e!==r)}export function setMcpServerEnabled(e,r){const s=isDefaultDisabledBuiltin(e)&&isMcpServerDisabled(e)===r;S(s=>{if(isDefaultDisabledBuiltin(e)){const o=s.enabledMcpServers||[],t=toggleMembership(o,e,r);return t===o?s:{...s,enabledMcpServers:t}}const o=s.disabledMcpServers||[],t=toggleMembership(o,e,!r);return t===o?s:{...s,disabledMcpServers:t}}),s&&U("tengu_builtin_mcp_toggle",{serverName:e,enabled:r})}
1
+ import{feature as e}from"../../recovery/bunBundleShim.js";import{createRequire as r}from"module";const s=r(import.meta.url);import{chmod as o,open as t,rename as n,stat as i,unlink as c}from"fs/promises";import a from"lodash-es/mapValues.js";import p from"lodash-es/memoize.js";import{dirname as l,join as f,parse as u}from"path";import{getPlatform as d}from"../../utils/platform.js";import{getPluginErrorMessage as m}from"../../types/plugin.js";import{isClaudeInChromeMCPServer as v}from"../../utils/claudeInChrome/common.js";import{getCurrentProjectConfig as g,getGlobalConfig as M,saveCurrentProjectConfig as S,saveGlobalConfig as h}from"../../utils/config.js";import{getCwd as w}from"../../utils/cwd.js";import{logForDebugging as C}from"../../utils/debug.js";import{getErrnoCode as y}from"../../utils/errors.js";import{getFsImplementation as P}from"../../utils/fsOperations.js";import{safeParseJSON as j}from"../../utils/json.js";import{logError as b}from"../../utils/log.js";import{getPluginMcpServers as x}from"../../utils/plugins/mcpPluginIntegration.js";import{loadAllPluginsCacheOnly as $}from"../../utils/plugins/pluginLoader.js";import{isSettingSourceEnabled as E}from"../../utils/settings/constants.js";import{getManagedFilePath as O}from"../../utils/settings/managedPath.js";import{isRestrictedToPluginOnly as F}from"../../utils/settings/pluginOnlyPolicy.js";import{getInitialSettings as A,getSettingsForSource as B}from"../../utils/settings/settings.js";import{isMcpServerCommandEntry as N,isMcpServerNameEntry as D,isMcpServerUrlEntry as k}from"../../utils/settings/types.js";import{jsonStringify as V}from"../../utils/slowOperations.js";import{logEvent as U}from"../analytics/index.js";import{fetchClaudeAIMcpConfigsIfEligible as _}from"./claudeai.js";import{expandEnvVarsInString as T}from"./envExpansion.js";import{McpJsonConfigSchema as W,McpServerConfigSchema as I}from"./types.js";import{getProjectMcpServerStatus as R}from"./utils.js";export function getEnterpriseMcpFilePath(){return f(O(),"managed-mcp.json")}function addScopeToServers(e,r){if(!e)return{};const s={};for(const[o,t]of Object.entries(e))s[o]={...t,scope:r};return s}async function writeMcpjsonFile(e){const r=f(w(),".mcp.json");let s;try{s=(await i(r)).mode}catch(e){if("ENOENT"!==y(e))throw e}const a=`${r}.tmp.${process.pid}.${Date.now()}`,p=await t(a,"w",s??420);try{await p.writeFile(V(e,null,2),{encoding:"utf8"}),await p.datasync()}finally{await p.close()}try{void 0!==s&&await o(a,s),await n(a,r)}catch(e){try{await c(a)}catch{}throw e}}function getServerCommandArray(e){if(void 0!==e.type&&"stdio"!==e.type)return null;const r=e;return[r.command,...r.args??[]]}function commandArraysMatch(e,r){return e.length===r.length&&e.every((e,s)=>e===r[s])}function getServerUrl(e){return"url"in e?e.url:null}const J=["/v2/session_ingress/shttp/mcp/","/v2/ccr-sessions/"];export function unwrapCcrProxyUrl(e){if(!J.some(r=>e.includes(r)))return e;try{const r=new URL(e);return r.searchParams.get("mcp_url")||e}catch{return e}}export function getMcpServerSignature(e){const r=getServerCommandArray(e);if(r)return`stdio:${V(r)}`;const s=getServerUrl(e);return s?`url:${unwrapCcrProxyUrl(s)}`:null}export function dedupPluginMcpServers(e,r){const s=new Map;for(const[e,o]of Object.entries(r)){const r=getMcpServerSignature(o);r&&!s.has(r)&&s.set(r,e)}const o={},t=[],n=new Map;for(const[r,i]of Object.entries(e)){const e=getMcpServerSignature(i);if(null===e){o[r]=i;continue}const c=s.get(e);if(void 0!==c){C(`Suppressing plugin MCP server "${r}": duplicates manually-configured "${c}"`),t.push({name:r,duplicateOf:c});continue}const a=n.get(e);void 0===a?(n.set(e,r),o[r]=i):(C(`Suppressing plugin MCP server "${r}": duplicates earlier plugin server "${a}"`),t.push({name:r,duplicateOf:a}))}return{servers:o,suppressed:t}}export function dedupClaudeAiMcpServers(e,r){const s=new Map;for(const[e,o]of Object.entries(r)){if(isMcpServerDisabled(e))continue;const r=getMcpServerSignature(o);r&&!s.has(r)&&s.set(r,e)}const o={},t=[];for(const[r,n]of Object.entries(e)){const e=getMcpServerSignature(n),i=null!==e?s.get(e):void 0;void 0===i?o[r]=n:(C(`Suppressing claude.ai connector "${r}": duplicates manually-configured "${i}"`),t.push({name:r,duplicateOf:i}))}return{servers:o,suppressed:t}}function urlMatchesPattern(e,r){const s=function(e){const r=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${r}$`)}(r);return s.test(e)}function isMcpServerDenied(e,r){const s=A();if(!s.deniedMcpServers)return!1;for(const r of s.deniedMcpServers)if(D(r)&&r.serverName===e)return!0;if(r){const e=getServerCommandArray(r);if(e)for(const r of s.deniedMcpServers)if(N(r)&&commandArraysMatch(r.serverCommand,e))return!0;const o=getServerUrl(r);if(o)for(const e of s.deniedMcpServers)if(k(e)&&urlMatchesPattern(o,e.serverUrl))return!0}return!1}function isMcpServerAllowedByPolicy(e,r){if(isMcpServerDenied(e,r))return!1;const s=shouldAllowManagedMcpServersOnly()?B("policySettings")??{}:A();if(!s.allowedMcpServers)return!0;if(0===s.allowedMcpServers.length)return!1;const o=s.allowedMcpServers.some(N),t=s.allowedMcpServers.some(k);if(r){const n=getServerCommandArray(r),i=getServerUrl(r);if(n){if(o){for(const e of s.allowedMcpServers)if(N(e)&&commandArraysMatch(e.serverCommand,n))return!0;return!1}for(const r of s.allowedMcpServers)if(D(r)&&r.serverName===e)return!0;return!1}if(i){if(t){for(const e of s.allowedMcpServers)if(k(e)&&urlMatchesPattern(i,e.serverUrl))return!0;return!1}for(const r of s.allowedMcpServers)if(D(r)&&r.serverName===e)return!0;return!1}for(const r of s.allowedMcpServers)if(D(r)&&r.serverName===e)return!0;return!1}for(const r of s.allowedMcpServers)if(D(r)&&r.serverName===e)return!0;return!1}export function filterMcpServersByPolicy(e){const r={},s=[];for(const[o,t]of Object.entries(e)){const e=t;"sdk"===e.type||isMcpServerAllowedByPolicy(o,e)?r[o]=t:s.push(o)}return{allowed:r,blocked:s}}function expandEnvVars(e){const r=[];function expandString(e){const{expanded:s,missingVars:o}=T(e);return r.push(...o),s}let s;switch(e.type){case void 0:case"stdio":{const r=e;s={...r,command:expandString(r.command),args:r.args.map(expandString),env:r.env?a(r.env,expandString):void 0};break}case"sse":case"http":case"ws":{const r=e;s={...r,url:expandString(r.url),headers:r.headers?a(r.headers,expandString):void 0};break}case"sse-ide":case"ws-ide":case"sdk":case"claudeai-proxy":s=e}return{expanded:s,missingVars:[...new Set(r)]}}export async function addMcpConfig(r,s,o){if(r.match(/[^a-zA-Z0-9_-]/))throw new Error(`Invalid name ${r}. Names can only contain letters, numbers, hyphens, and underscores.`);if(v(r))throw new Error(`Cannot add MCP server "${r}": this name is reserved.`);if(e("CHICAGO_MCP")){const{isComputerUseMCPServer:e}=await import("../../utils/computerUse/common.js");if(e(r))throw new Error(`Cannot add MCP server "${r}": this name is reserved.`)}const{isDatabaseMCPServer:t}=await import("../../utils/databaseMcp/common.js");if(t(r))throw new Error(`Cannot add MCP server "${r}": this name is reserved.`);const{isMetaMCPServer:n}=await import("../../utils/metaMcp/common.js");if(n(r))throw new Error(`Cannot add MCP server "${r}": this name is reserved.`);const{isComputerControlMCPServer:i}=await import("../../utils/computerControlMcp/common.js");if(i(r))throw new Error(`Cannot add MCP server "${r}": this name is reserved.`);if(doesEnterpriseMcpConfigExist())throw new Error("Cannot add MCP server: enterprise MCP configuration is active and has exclusive control over MCP servers");const c=I().safeParse(s);if(!c.success){const e=c.error.issues.map(e=>`${e.path.join(".")}: ${e.message}`).join(", ");throw new Error(`Invalid configuration: ${e}`)}const a=c.data;if(isMcpServerDenied(r,a))throw new Error(`Cannot add MCP server "${r}": server is explicitly blocked by enterprise policy`);if(!isMcpServerAllowedByPolicy(r,a))throw new Error(`Cannot add MCP server "${r}": not allowed by enterprise policy`);switch(o){case"project":{const{servers:e}=getProjectMcpConfigsFromCwd();if(e[r])throw new Error(`MCP server ${r} already exists in .mcp.json`);break}case"user":{const e=M();if(e.mcpServers?.[r])throw new Error(`MCP server ${r} already exists in user config`);break}case"local":{const e=g();if(e.mcpServers?.[r])throw new Error(`MCP server ${r} already exists in local config`);break}case"dynamic":throw new Error("Cannot add MCP server to scope: dynamic");case"enterprise":throw new Error("Cannot add MCP server to scope: enterprise");case"claudeai":throw new Error("Cannot add MCP server to scope: claudeai")}switch(o){case"project":{const{servers:e}=getProjectMcpConfigsFromCwd(),s={};for(const[r,o]of Object.entries(e)){const{scope:e,...t}=o;s[r]=t}s[r]=a;const o={mcpServers:s};try{await writeMcpjsonFile(o)}catch(e){throw new Error(`Failed to write to .mcp.json: ${e}`)}break}case"user":h(e=>({...e,mcpServers:{...e.mcpServers,[r]:a}}));break;case"local":S(e=>({...e,mcpServers:{...e.mcpServers,[r]:a}}));break;default:throw new Error(`Cannot add MCP server to scope: ${o}`)}}export async function removeMcpConfig(e,r){switch(r){case"project":{const{servers:r}=getProjectMcpConfigsFromCwd();if(!r[e])throw new Error(`No MCP server found with name: ${e} in .mcp.json`);const s={};for(const[o,t]of Object.entries(r))if(o!==e){const{scope:e,...r}=t;s[o]=r}const o={mcpServers:s};try{await writeMcpjsonFile(o)}catch(e){throw new Error(`Failed to remove from .mcp.json: ${e}`)}break}case"user":{const r=M();if(!r.mcpServers?.[e])throw new Error(`No user-scoped MCP server found with name: ${e}`);h(r=>{const{[e]:s,...o}=r.mcpServers??{};return{...r,mcpServers:o}});break}case"local":{const r=g();if(!r.mcpServers?.[e])throw new Error(`No project-local MCP server found with name: ${e}`);S(r=>{const{[e]:s,...o}=r.mcpServers??{};return{...r,mcpServers:o}});break}default:throw new Error(`Cannot remove MCP server from scope: ${r}`)}}export function getProjectMcpConfigsFromCwd(){if(!E("projectSettings"))return{servers:{},errors:[]};const e=f(w(),".mcp.json"),{config:r,errors:s}=parseMcpConfigFromFilePath({filePath:e,expandVars:!0,scope:"project"});if(!r){const r=s.filter(e=>!e.message.startsWith("MCP config file not found"));return r.length>0?(C(`MCP config errors for ${e}: ${V(r.map(e=>e.message))}`,{level:"error"}),{servers:{},errors:r}):{servers:{},errors:[]}}return{servers:r.mcpServers?addScopeToServers(r.mcpServers,"project"):{},errors:s||[]}}export function getMcpConfigsByScope(e){const r={project:"projectSettings",user:"userSettings",local:"localSettings"};if(e in r&&!E(r[e]))return{servers:{},errors:[]};switch(e){case"project":{const r={},s=[],o=[];let t=w();for(;t!==u(t).root;)o.push(t),t=l(t);for(const t of o.reverse()){const o=f(t,".mcp.json"),{config:n,errors:i}=parseMcpConfigFromFilePath({filePath:o,expandVars:!0,scope:"project"});if(!n){const e=i.filter(e=>!e.message.startsWith("MCP config file not found"));e.length>0&&(C(`MCP config errors for ${o}: ${V(e.map(e=>e.message))}`,{level:"error"}),s.push(...e));continue}n.mcpServers&&Object.assign(r,addScopeToServers(n.mcpServers,e)),i.length>0&&s.push(...i)}return{servers:r,errors:s}}case"user":{const r=M().mcpServers;if(!r)return{servers:{},errors:[]};const{config:s,errors:o}=parseMcpConfig({configObject:{mcpServers:r},expandVars:!0,scope:"user"});return{servers:addScopeToServers(s?.mcpServers,e),errors:o}}case"local":{const r=g().mcpServers;if(!r)return{servers:{},errors:[]};const{config:s,errors:o}=parseMcpConfig({configObject:{mcpServers:r},expandVars:!0,scope:"local"});return{servers:addScopeToServers(s?.mcpServers,e),errors:o}}case"enterprise":{const r=getEnterpriseMcpFilePath(),{config:s,errors:o}=parseMcpConfigFromFilePath({filePath:r,expandVars:!0,scope:"enterprise"});if(!s){const e=o.filter(e=>!e.message.startsWith("MCP config file not found"));return e.length>0?(C(`Enterprise MCP config errors for ${r}: ${V(e.map(e=>e.message))}`,{level:"error"}),{servers:{},errors:e}):{servers:{},errors:[]}}return{servers:addScopeToServers(s.mcpServers,e),errors:o}}}}export function getMcpConfigByName(e){const{servers:r}=getMcpConfigsByScope("enterprise");if(F("mcp"))return r[e]??null;const{servers:s}=getMcpConfigsByScope("user"),{servers:o}=getMcpConfigsByScope("project"),{servers:t}=getMcpConfigsByScope("local");return r[e]?r[e]:t[e]?t[e]:o[e]?o[e]:s[e]?s[e]:null}export async function getClaudeCodeMcpConfigs(e={},r=Promise.resolve({})){const{servers:s}=getMcpConfigsByScope("enterprise");if(doesEnterpriseMcpConfigExist()){const e={};for(const[r,o]of Object.entries(s))isMcpServerAllowedByPolicy(r,o)&&(e[r]=o);return{servers:e,errors:[]}}const o=F("mcp"),t={servers:{}},{servers:n}=o?t:getMcpConfigsByScope("user"),{servers:i}=o?t:getMcpConfigsByScope("project"),{servers:c}=o?t:getMcpConfigsByScope("local"),a={},p=await $(),l=[];if(p.errors.length>0)for(const e of p.errors)if("mcp-config-invalid"===e.type||"mcpb-download-failed"===e.type||"mcpb-extract-failed"===e.type||"mcpb-invalid-manifest"===e.type){const r=`Plugin MCP loading error - ${e.type}: ${m(e)}`;b(new Error(r))}else{const r=e.type;C(`Plugin not available for MCP: ${e.source} - error type: ${r}`)}const f=await Promise.all(p.enabled.map(e=>x(e,l)));for(const e of f)e&&Object.assign(a,e);if(l.length>0)for(const e of l){const r=`Plugin MCP server error - ${e.type}: ${m(e)}`;b(new Error(r))}const u={};for(const[e,r]of Object.entries(i))"approved"===R(e)&&(u[e]=r);const d=await r,v={};for(const[r,s]of Object.entries({...n,...u,...c,...e,...d}))!isMcpServerDisabled(r)&&isMcpServerAllowedByPolicy(r,s)&&(v[r]=s);const g={},M={};for(const[e,r]of Object.entries(a))isMcpServerDisabled(e)||!isMcpServerAllowedByPolicy(e,r)?M[e]=r:g[e]=r;const{servers:S,suppressed:h}=dedupPluginMcpServers(g,v);Object.assign(S,M);for(const{name:e,duplicateOf:r}of h){const s=e.split(":");"plugin"!==s[0]||s.length<3||l.push({type:"mcp-server-suppressed-duplicate",source:e,plugin:s[1],serverName:s.slice(2).join(":"),duplicateOf:r})}const w=Object.assign({},S,n,u,c),y={};for(const[e,r]of Object.entries(w))isMcpServerAllowedByPolicy(e,r)&&(y[e]=r);return{servers:y,errors:l}}export async function getAllMcpConfigs(){if(doesEnterpriseMcpConfigExist())return getClaudeCodeMcpConfigs();const e=_(),{servers:r,errors:s}=await getClaudeCodeMcpConfigs({},e),{allowed:o}=filterMcpServersByPolicy(await e),{servers:t}=dedupClaudeAiMcpServers(o,r);return{servers:Object.assign({},t,r),errors:s}}export function parseMcpConfig(e){const{configObject:r,expandVars:s,scope:o,filePath:t}=e,n=W().safeParse(r);if(!n.success)return{config:null,errors:n.error.issues.map(e=>({...t&&{file:t},path:e.path.join("."),message:"Does not adhere to MCP server configuration schema",mcpErrorMetadata:{scope:o,severity:"fatal"}}))};const i=[],c={};for(const[e,r]of Object.entries(n.data.mcpServers)){let n=r;if(s){const{expanded:s,missingVars:c}=expandEnvVars(r);c.length>0&&i.push({...t&&{file:t},path:`mcpServers.${e}`,message:`Missing environment variables: ${c.join(", ")}`,suggestion:`Set the following environment variables: ${c.join(", ")}`,mcpErrorMetadata:{scope:o,serverName:e,severity:"warning"}}),n=s}"windows"!==d()||n.type&&"stdio"!==n.type||"npx"!==n.command&&!n.command.endsWith("\\npx")&&!n.command.endsWith("/npx")||i.push({...t&&{file:t},path:`mcpServers.${e}`,message:"Windows requires 'cmd /c' wrapper to execute npx",suggestion:'Change command to "cmd" with args ["/c", "npx", ...]',mcpErrorMetadata:{scope:o,serverName:e,severity:"warning"}}),c[e]=n}return{config:{mcpServers:c},errors:i}}export function parseMcpConfigFromFilePath(e){const{filePath:r,expandVars:s,scope:o}=e,t=P();let n;try{n=t.readFileSync(r,{encoding:"utf8"})}catch(e){return"ENOENT"===y(e)?{config:null,errors:[{file:r,path:"",message:`MCP config file not found: ${r}`,suggestion:"Check that the file path is correct",mcpErrorMetadata:{scope:o,severity:"fatal"}}]}:(C(`MCP config read error for ${r} (scope=${o}): ${e}`,{level:"error"}),{config:null,errors:[{file:r,path:"",message:`Failed to read file: ${e}`,suggestion:"Check file permissions and ensure the file exists",mcpErrorMetadata:{scope:o,severity:"fatal"}}]})}const i=j(n);return i?parseMcpConfig({configObject:i,expandVars:s,scope:o,filePath:r}):(C(`MCP config is not valid JSON: ${r} (scope=${o}, length=${n.length}, first100=${V(n.slice(0,100))})`,{level:"error"}),{config:null,errors:[{file:r,path:"",message:"MCP config is not a valid JSON",suggestion:"Fix the JSON syntax errors in the file",mcpErrorMetadata:{scope:o,severity:"fatal"}}]})}export const doesEnterpriseMcpConfigExist=p(()=>{const{config:e}=parseMcpConfigFromFilePath({filePath:getEnterpriseMcpFilePath(),expandVars:!0,scope:"enterprise"});return null!==e});export function shouldAllowManagedMcpServersOnly(){return!0===B("policySettings")?.allowManagedMcpServersOnly}export function areMcpConfigsAllowedWithEnterpriseMcpConfig(e){return Object.values(e).every(e=>"sdk"===e.type&&"claude-vscode"===e.name)}const z=e("CHICAGO_MCP")?s("../../utils/computerUse/common.js").COMPUTER_USE_MCP_SERVER_NAME:null;function isDefaultDisabledBuiltin(e){return null!==z&&e===z}export function isMcpServerDisabled(e){const r=g();if(isDefaultDisabledBuiltin(e)){return!(r.enabledMcpServers||[]).includes(e)}return(r.disabledMcpServers||[]).includes(e)}function toggleMembership(e,r,s){return e.includes(r)===s?e:s?[...e,r]:e.filter(e=>e!==r)}export function setMcpServerEnabled(e,r){const s=isDefaultDisabledBuiltin(e)&&isMcpServerDisabled(e)===r;S(s=>{if(isDefaultDisabledBuiltin(e)){const o=s.enabledMcpServers||[],t=toggleMembership(o,e,r);return t===o?s:{...s,enabledMcpServers:t}}const o=s.disabledMcpServers||[],t=toggleMembership(o,e,!r);return t===o?s:{...s,disabledMcpServers:t}}),s&&U("tengu_builtin_mcp_toggle",{serverName:e,enabled:r})}
@@ -1 +1 @@
1
- import{MACRO as e}from"../recovery/bunBundleShim.js";import t from"chalk";import{exec as r}from"child_process";import{execa as n}from"execa";import{mkdir as o,stat as s}from"fs/promises";import i from"lodash-es/memoize.js";import{CLAUDE_AI_PROFILE_SCOPE as c}from"../constants/oauth.js";import{logEvent as a}from"../services/analytics/index.js";import{GEMINI_CLI_OAUTH_CLIENT_ID as u,GEMINI_CLI_OAUTH_CLIENT_SECRET as p,GEMINI_CLI_OAUTH_SCOPES as l,GEMINI_CLI_OAUTH_TOKEN_URL as A}from"../constants/geminiOAuth.js";import{getModelStrings as d}from"./model/modelStrings.js";import{getAPIProvider as h,isOpenAICompatibleProvider as f}from"./model/providers.js";import{getResolvedProviderProfileId as _,ensureProviderProfile as g,isDefaultProfileId as O,isProfiledProvider as T,resolveProviderProfile as E}from"./model/providerProfiles.js";import{getIsNonInteractiveSession as m,preferThirdPartyAuthentication as k}from"../bootstrap/state.js";import{getMockSubscriptionType as y,shouldUseMockSubscription as C}from"../services/mockRateLimits.js";import{isOAuthTokenExpired as v,refreshOpenAIOAuthToken as I,refreshOAuthToken as K,shouldUseClaudeAIAuth as P}from"../services/oauth/client.js";import{getOauthProfileFromOauthToken as S}from"../services/oauth/getOauthProfile.js";import{getApiKeyFromFileDescriptor as x,getOAuthTokenFromFileDescriptor as w}from"./authFileDescriptor.js";import{maybeRemoveApiKeyFromMacOSKeychainThrows as N,normalizeApiKeyForConfig as R}from"./authPortable.js";import{checkStsCallerIdentity as D,clearAwsIniCache as H,isValidAwsStsOutput as b}from"./aws.js";import{AwsAuthStatusManager as U}from"./awsAuthStatusManager.js";import{clearBetasCaches as L}from"./betas.js";import{checkHasTrustDialogAccepted as j,getGlobalConfig as G,saveGlobalConfig as F}from"./config.js";import{logAntError as M,logForDebugging as Y}from"./debug.js";import{getClaudeConfigHomeDir as $,isBareMode as B,isEnvTruthy as X,isRunningOnHomespace as z}from"./envUtils.js";import{errorMessage as W}from"./errors.js";import{execSyncWithDefaults_DEPRECATED as q}from"./execFileNoThrow.js";import*as V from"./lockfile.js";import{logError as J}from"./log.js";import{memoizeWithTTLAsync as Z}from"./memoize.js";import{getSecureStorage as Q}from"./secureStorage/index.js";import{clearLegacyApiKeyPrefetch as ee,getLegacyApiKeyPrefetchResult as te}from"./secureStorage/keychainPrefetch.js";import{clearKeychainCache as re,getMacOsKeychainStorageServiceName as ne,getUsername as oe}from"./secureStorage/macOsKeychainHelpers.js";import{getLegacyCredentialsFilePath as se,getSecureStorageDbPath as ie}from"./secureStorage/sqliteStorage.js";import{getSettings_DEPRECATED as ce,getSettingsForSource as ae}from"./settings/settings.js";import{sleep as ue}from"./sleep.js";import{jsonParse as pe}from"./slowOperations.js";import{clearToolSchemaCache as le}from"./toolSchemaCache.js";function isManagedOAuthContext(){return X(process.env.CONTEXT_CODE_REMOTE)||X(process.env.CLAUDE_CODE_REMOTE)||"claude-desktop"===process.env.CLAUDE_CODE_ENTRYPOINT}export function isAnthropicAuthEnabled(){if(B())return!1;if(process.env.ANTHROPIC_UNIX_SOCKET)return!(!process.env.CONTEXT_CODE_OAUTH_TOKEN&&!process.env.CLAUDE_CODE_OAUTH_TOKEN);const e=h(),t=X(process.env.CONTEXT_CODE_USE_BEDROCK)||X(process.env.CLAUDE_CODE_USE_BEDROCK)||X(process.env.CONTEXT_CODE_USE_VERTEX)||X(process.env.CLAUDE_CODE_USE_VERTEX)||X(process.env.CONTEXT_CODE_USE_FOUNDRY)||X(process.env.CLAUDE_CODE_USE_FOUNDRY)||f(e)||"custom-anthropic"===e,r=(ce()||{}).apiKeyHelper,n=process.env.ANTHROPIC_AUTH_TOKEN||r||process.env.CONTEXT_CODE_API_KEY_FILE_DESCRIPTOR||process.env.CLAUDE_CODE_API_KEY_FILE_DESCRIPTOR,{source:o}=getAnthropicApiKeyWithSource({skipRetrievingKeyFromApiKeyHelper:!0}),s="ANTHROPIC_API_KEY"===o||"apiKeyHelper"===o;return!(t||n&&!isManagedOAuthContext()||s&&!isManagedOAuthContext())}export function getAuthTokenSource(){const e=h();if(f(e))return{source:e,hasToken:Boolean(getOpenAICompatibleAccessToken(e))};if(B())return getConfiguredApiKeyHelper()?{source:"apiKeyHelper",hasToken:!0}:{source:"none",hasToken:!1};if(process.env.ANTHROPIC_AUTH_TOKEN&&!isManagedOAuthContext())return{source:"ANTHROPIC_AUTH_TOKEN",hasToken:!0};if(isManagedOAuthContext()&&(process.env.CONTEXT_CODE_OAUTH_TOKEN||process.env.CLAUDE_CODE_OAUTH_TOKEN))return{source:"CLAUDE_CODE_OAUTH_TOKEN",hasToken:!0};if(isManagedOAuthContext()?w():null)return process.env.CONTEXT_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR||process.env.CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR?{source:"CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR",hasToken:!0}:{source:"CCR_OAUTH_TOKEN_FILE",hasToken:!0};if(getConfiguredApiKeyHelper()&&!isManagedOAuthContext())return{source:"apiKeyHelper",hasToken:!0};const t=getClaudeAIOAuthTokens();return P(t?.scopes)&&t?.accessToken?{source:"claude.ai",hasToken:!0}:{source:"none",hasToken:!1}}const Ae={gmi:"GMI_API_KEY",novita:"NOVITA_API_KEY",stepfun:"STEPFUN_API_KEY",huggingface:"HF_TOKEN","opencode-zen":"OPENCODE_ZEN_API_KEY",arcee:"ARCEEAI_API_KEY",alibaba:"DASHSCOPE_API_KEY",kimi:"KIMI_API_KEY"};function getProviderOauthStorageKey(e){return"claude"===e?"claudeAiOauth":"openAiOauth"}function shouldUseLegacyProviderOauthFallback(e){return"openai"===e}export function getStoredProviderOAuthTokens(e,t){try{const r=Q().read();if(t){const n=r?.providerProfileOauth?.[t];if(n?.accessToken)return n;if(!O(e,t)&&!shouldUseLegacyProviderOauthFallback(e))return null}if("gemini-google"===e)return null;if(!shouldUseLegacyProviderOauthFallback(e))return null;const n=r?.[getProviderOauthStorageKey(e)];return n?.accessToken?n:null}catch{return null}}export function hasStoredProviderOAuthTokens(e,t){if(t)return Boolean(getStoredProviderOAuthTokens(e,t));try{const t=Q().read(),r=Object.entries(t?.providerProfileOauth??{}).some(([t,r])=>t.startsWith(`${e}/`)&&"object"==typeof r&&null!==r&&"string"==typeof r.accessToken&&r.accessToken.trim());return shouldUseLegacyProviderOauthFallback(e)?Boolean(r||t?.[getProviderOauthStorageKey(e)]?.accessToken):Boolean(r)}catch{return!1}}export async function renameProviderScopedCredentials(e,t){if(!e||!t||e===t)return;const r=Q(),n=r.read()||{},o={...n.providerProfileApiKeys??{}},s={...n.providerProfileOauth??{}};e in o&&(o[t]=o[e],delete o[e]),e in s&&(s[t]=s[e],delete s[e]);if(!r.update({...n,providerProfileApiKeys:o,providerProfileOauth:s}).success)throw new Error("No se pudieron mover las credenciales del perfil.")}export async function removeProviderScopedCredentials(e){if(!e)return;const t=Q(),r=t.read()||{},n={...r.providerProfileApiKeys??{}},o={...r.providerProfileOauth??{}};delete n[e],delete o[e];if(!t.update({...r,providerProfileApiKeys:n,providerProfileOauth:o}).success)throw new Error("No se pudieron eliminar las credenciales del perfil.")}export async function removeAllProviderScopedCredentials(){const e=Q(),t=e.read()||{};if(!e.update({...t,providerProfileApiKeys:{},providerProfileOauth:{}}).success)throw new Error("No se pudieron eliminar las credenciales scoped de perfiles.")}export function getAnthropicApiKey(){const{key:e}=getAnthropicApiKeyWithSource();return e}export function hasAnthropicApiKeyAuth(){const{key:e,source:t}=getAnthropicApiKeyWithSource({skipRetrievingKeyFromApiKeyHelper:!0});return null!==e&&"none"!==t}export function getAnthropicApiKeyWithSource(e={}){if(f(h()))return{key:null,source:"none"};if(B())return process.env.ANTHROPIC_API_KEY?{key:process.env.ANTHROPIC_API_KEY,source:"ANTHROPIC_API_KEY"}:getConfiguredApiKeyHelper()?{key:e.skipRetrievingKeyFromApiKeyHelper?null:getApiKeyFromApiKeyHelperCached(),source:"apiKeyHelper"}:{key:null,source:"none"};const t=z()?void 0:process.env.ANTHROPIC_API_KEY;if(k()&&t)return{key:t,source:"ANTHROPIC_API_KEY"};if(X(process.env.CI)||"test"===process.env.NODE_ENV){const e=x();if(e)return{key:e,source:"ANTHROPIC_API_KEY"};if(!(t||process.env.CONTEXT_CODE_OAUTH_TOKEN||process.env.CLAUDE_CODE_OAUTH_TOKEN||process.env.CONTEXT_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR||process.env.CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR))throw new Error("ANTHROPIC_API_KEY or CONTEXT_CODE_OAUTH_TOKEN (legacy: CLAUDE_CODE_OAUTH_TOKEN) env var is required");return t?{key:t,source:"ANTHROPIC_API_KEY"}:{key:null,source:"none"}}if(t&&G().customApiKeyResponses?.approved?.includes(R(t)))return{key:t,source:"ANTHROPIC_API_KEY"};const r=x();if(r)return{key:r,source:"ANTHROPIC_API_KEY"};if(getConfiguredApiKeyHelper())return e.skipRetrievingKeyFromApiKeyHelper?{key:null,source:"apiKeyHelper"}:{key:getApiKeyFromApiKeyHelperCached(),source:"apiKeyHelper"};const n=getApiKeyFromConfigOrMacOSKeychain();return n||{key:null,source:"none"}}export function getConfiguredApiKeyHelper(){if(B())return ae("flagSettings")?.apiKeyHelper;return(ce()||{}).apiKeyHelper}function isApiKeyHelperFromProjectOrLocalSettings(){const e=getConfiguredApiKeyHelper();if(!e)return!1;const t=ae("projectSettings"),r=ae("localSettings");return t?.apiKeyHelper===e||r?.apiKeyHelper===e}function getConfiguredAwsAuthRefresh(){return(ce()||{}).awsAuthRefresh}export function isAwsAuthRefreshFromProjectSettings(){const e=getConfiguredAwsAuthRefresh();if(!e)return!1;const t=ae("projectSettings"),r=ae("localSettings");return t?.awsAuthRefresh===e||r?.awsAuthRefresh===e}function getConfiguredAwsCredentialExport(){return(ce()||{}).awsCredentialExport}export function isAwsCredentialExportFromProjectSettings(){const e=getConfiguredAwsCredentialExport();if(!e)return!1;const t=ae("projectSettings"),r=ae("localSettings");return t?.awsCredentialExport===e||r?.awsCredentialExport===e}export function calculateApiKeyHelperTTL(){const e=process.env.CONTEXT_CODE_API_KEY_HELPER_TTL_MS??process.env.CLAUDE_CODE_API_KEY_HELPER_TTL_MS;if(e){const t=parseInt(e,10);if(!Number.isNaN(t)&&t>=0)return t;Y(`Found CLAUDE_CODE_API_KEY_HELPER_TTL_MS env var, but it was not a valid number. Got ${e}`,{level:"error"})}return 3e5}let de=null,he=null,fe=0;export function getApiKeyHelperElapsedMs(){const e=he?.startedAt;return e?Date.now()-e:0}export async function getApiKeyFromApiKeyHelper(e){if(!getConfiguredApiKeyHelper())return null;const t=calculateApiKeyHelperTTL();return de?(Date.now()-de.timestamp<t||he||(he={promise:_runAndCache(e,!1,fe),startedAt:null}),de.value):(he||(he={promise:_runAndCache(e,!0,fe),startedAt:Date.now()}),he.promise)}async function _runAndCache(r,o,s){try{const t=await async function(t){const r=getConfiguredApiKeyHelper();if(!r)return null;if(isApiKeyHelperFromProjectOrLocalSettings()){if(!j()&&!t){const t=new Error(`Security: apiKeyHelper executed before workspace trust is confirmed. If you see this message, post in ${e.FEEDBACK_CHANNEL}.`);return M("apiKeyHelper invoked before trust check",t),a("tengu_apiKeyHelper_missing_trust11",{}),null}}const o=await n(r,{shell:!0,timeout:6e5,reject:!1});if(o.failed){const e=o.timedOut?"timed out":`exited ${o.exitCode}`,t=o.stderr?.trim();throw new Error(t?`${e}: ${t}`:e)}const s=o.stdout?.trim();if(!s)throw new Error("did not return a value");return s}(r);return s!==fe||null!==t&&(de={value:t,timestamp:Date.now()}),t}catch(e){if(s!==fe)return" ";const r=e instanceof Error?e.message:String(e);return console.error(t.red(`apiKeyHelper failed: ${r}`)),Y(`Error getting API key from apiKeyHelper: ${r}`,{level:"error"}),!o&&de&&" "!==de.value?(de={...de,timestamp:Date.now()},de.value):(de={value:" ",timestamp:Date.now()}," ")}finally{s===fe&&(he=null)}}export function getApiKeyFromApiKeyHelperCached(){return de?.value??null}export function clearApiKeyHelperCache(){fe++,de=null,he=null}export function prefetchApiKeyFromApiKeyHelperIfSafe(e){isApiKeyHelperFromProjectOrLocalSettings()&&!j()||getApiKeyFromApiKeyHelper(e)}const _e=18e4;export function refreshAwsAuth(e){Y("Running AWS auth refresh command");const n=U.getInstance();return n.startAuthentication(),new Promise(o=>{const s=r(e,{timeout:_e});s.stdout.on("data",e=>{const t=e.toString().trim();t&&(n.addOutput(t),Y(t,{level:"debug"}))}),s.stderr.on("data",e=>{const t=e.toString().trim();t&&(n.setError(t),Y(t,{level:"error"}))}),s.on("close",(e,r)=>{if(0===e)Y("AWS auth refresh completed successfully"),n.endAuthentication(!0),o(!0);else{const e="SIGTERM"===r?t.red("AWS auth refresh timed out after 3 minutes. Run your auth command manually in a separate terminal."):t.red("Error running awsAuthRefresh (in settings or ~/.context.json):");console.error(e),n.endAuthentication(!1),o(!1)}})})}export const refreshAndGetAwsCredentials=Z(async()=>{const r=await async function(){const t=getConfiguredAwsAuthRefresh();if(!t)return!1;if(isAwsAuthRefreshFromProjectSettings()&&!j()&&!m()){const t=new Error(`Security: awsAuthRefresh executed before workspace trust is confirmed. If you see this message, post in ${e.FEEDBACK_CHANNEL}.`);return M("awsAuthRefresh invoked before trust check",t),a("tengu_awsAuthRefresh_missing_trust",{}),!1}try{return Y("Fetching AWS caller identity for AWS auth refresh command"),await D(),Y("Fetched AWS caller identity, skipping AWS auth refresh command"),!1}catch{return refreshAwsAuth(t)}}(),o=await async function(){const r=getConfiguredAwsCredentialExport();if(!r)return null;if(isAwsCredentialExportFromProjectSettings()&&!j()&&!m()){const t=new Error(`Security: awsCredentialExport executed before workspace trust is confirmed. If you see this message, post in ${e.FEEDBACK_CHANNEL}.`);return M("awsCredentialExport invoked before trust check",t),a("tengu_awsCredentialExport_missing_trust",{}),null}try{return Y("Fetching AWS caller identity for credential export command"),await D(),Y("Fetched AWS caller identity, skipping AWS credential export command"),null}catch{try{Y("Running AWS credential export command");const e=await n(r,{shell:!0,reject:!1});if(0!==e.exitCode||!e.stdout)throw new Error("awsCredentialExport did not return a valid value");const t=pe(e.stdout.trim());if(!b(t))throw new Error("awsCredentialExport did not return valid AWS STS output structure");return Y("AWS credentials retrieved from awsCredentialExport"),{accessKeyId:t.Credentials.AccessKeyId,secretAccessKey:t.Credentials.SecretAccessKey,sessionToken:t.Credentials.SessionToken}}catch(e){const r=t.red("Error getting AWS credentials from awsCredentialExport (in settings or ~/.context.json):");return e instanceof Error?console.error(r,e.message):console.error(r,e),null}}}();return(r||o)&&await H(),o},36e5);export function clearAwsCredentialsCache(){refreshAndGetAwsCredentials.cache.clear()}function getConfiguredGcpAuthRefresh(){return(ce()||{}).gcpAuthRefresh}export function isGcpAuthRefreshFromProjectSettings(){const e=getConfiguredGcpAuthRefresh();if(!e)return!1;const t=ae("projectSettings"),r=ae("localSettings");return t?.gcpAuthRefresh===e||r?.gcpAuthRefresh===e}const ge=l;export async function checkGcpCredentialsValid(){try{const{GoogleAuth:e}=await import("google-auth-library"),t=new e({scopes:["https://www.googleapis.com/auth/cloud-platform"]}),r=(async()=>{const e=await t.getClient();await e.getAccessToken()})(),n=ue(5e3).then(()=>{throw new GcpCredentialsTimeoutError("GCP credentials check timed out")});return await Promise.race([r,n]),!0}catch{return!1}}const Oe=18e4;export function refreshGcpAuth(e){Y("Running GCP auth refresh command");const n=U.getInstance();return n.startAuthentication(),new Promise(o=>{const s=r(e,{timeout:Oe});s.stdout.on("data",e=>{const t=e.toString().trim();t&&(n.addOutput(t),Y(t,{level:"debug"}))}),s.stderr.on("data",e=>{const t=e.toString().trim();t&&(n.setError(t),Y(t,{level:"error"}))}),s.on("close",(e,r)=>{if(0===e)Y("GCP auth refresh completed successfully"),n.endAuthentication(!0),o(!0);else{const e="SIGTERM"===r?t.red("GCP auth refresh timed out after 3 minutes. Run your auth command manually in a separate terminal."):t.red("Error running gcpAuthRefresh (in settings or ~/.context.json):");console.error(e),n.endAuthentication(!1),o(!1)}})})}export const refreshGcpCredentialsIfNeeded=Z(async()=>await async function(){const t=getConfiguredGcpAuthRefresh();if(!t)return!1;if(isGcpAuthRefreshFromProjectSettings()&&!j()&&!m()){const t=new Error(`Security: gcpAuthRefresh executed before workspace trust is confirmed. If you see this message, post in ${e.FEEDBACK_CHANNEL}.`);return M("gcpAuthRefresh invoked before trust check",t),a("tengu_gcpAuthRefresh_missing_trust",{}),!1}try{if(Y("Checking GCP credentials validity for auth refresh"),await checkGcpCredentialsValid())return Y("GCP credentials are valid, skipping auth refresh command"),!1}catch{}return refreshGcpAuth(t)}(),36e5);export function clearGcpCredentialsCache(){refreshGcpCredentialsIfNeeded.cache.clear()}export function prefetchGcpCredentialsIfSafe(){if(getConfiguredGcpAuthRefresh()){if(isGcpAuthRefreshFromProjectSettings()){if(!j()&&!m())return}refreshGcpCredentialsIfNeeded()}}export function prefetchAwsCredentialsAndBedRockInfoIfSafe(){const e=getConfiguredAwsAuthRefresh(),t=getConfiguredAwsCredentialExport();if(e||t){if(isAwsAuthRefreshFromProjectSettings()||isAwsCredentialExportFromProjectSettings()){if(!j()&&!m())return}refreshAndGetAwsCredentials(),d()}}export const getApiKeyFromConfigOrMacOSKeychain=i(()=>{if("darwin"===process.platform){const e=te();if(e){if(e.stdout)return{key:e.stdout,source:"/login managed key"}}else{const e=ne();try{const t=q(`security find-generic-password -a $USER -w -s "${e}"`);if(t)return{key:t,source:"/login managed key"}}catch(e){J(e)}}}const e=G();return e.primaryApiKey?{key:e.primaryApiKey,source:"/login managed key"}:null});function isValidApiKey(e){return/^[a-zA-Z0-9-_\.]+$/.test(e)}function getStoredProviderApiKey(e,t){try{const r=Q().read();if(t){const n=r?.providerProfileApiKeys?.[t];if("string"==typeof n&&n.trim())return n;if(!O(e,t))return null}return r?.providerApiKeys?.[e]??null}catch{return null}}export function hasStoredProviderApiKey(e,t){return Boolean(getStoredProviderApiKey(e,t))}export async function saveProviderApiKey(e,t){if(!isValidApiKey(t))throw new Error("Formato de clave API inválido. La clave API solo debe contener caracteres alfanuméricos, guiones, guiones bajos y puntos.");const r=Q(),n=r.read()||{},o=T(e)?E(e,{createIfMissing:!0})?.id??null:null;if(!r.update({...n,providerApiKeys:{...n.providerApiKeys??{},[e]:t},...o?{providerProfileApiKeys:{...n.providerProfileApiKeys??{},[o]:t}}:{}}).success)throw new Error(`Failed to save ${e} API key`)}export async function removeProviderApiKey(e){const t=Q(),r=t.read()||{},n={...r.providerApiKeys??{}};delete n[e];const o={...r.providerProfileApiKeys??{}};if(T(e)){const t=_(e);t&&delete o[t]}if(!t.update({...r,providerApiKeys:n,providerProfileApiKeys:o}).success)throw new Error(`Failed to remove ${e} API key`)}export async function saveApiKey(e){if(!isValidApiKey(e))throw new Error("Formato de clave API inválido. La clave API solo debe contener caracteres alfanuméricos, guiones, guiones bajos y puntos.");await maybeRemoveApiKeyFromMacOSKeychain();let t=!1;if("darwin"===process.platform)try{const r=ne(),o=oe(),s=`add-generic-password -U -a "${o}" -s "${r}" -X "${Buffer.from(e,"utf-8").toString("hex")}"\n`;await n("security",["-i"],{input:s,reject:!1}),a("tengu_api_key_saved_to_keychain",{}),t=!0}catch(e){J(e),a("tengu_api_key_keychain_error",{error:W(e)}),a("tengu_api_key_saved_to_config",{})}else a("tengu_api_key_saved_to_config",{});const r=R(e);F(n=>{const o=n.customApiKeyResponses?.approved??[];return{...n,primaryApiKey:t?n.primaryApiKey:e,customApiKeyResponses:{...n.customApiKeyResponses,approved:o.includes(r)?o:[...o,r],rejected:n.customApiKeyResponses?.rejected??[]}}}),getApiKeyFromConfigOrMacOSKeychain.cache.clear?.(),ee()}export function isCustomApiKeyApproved(e){const t=G(),r=R(e);return t.customApiKeyResponses?.approved?.includes(r)??!1}export async function removeApiKey(){await maybeRemoveApiKeyFromMacOSKeychain(),F(e=>({...e,primaryApiKey:void 0})),getApiKeyFromConfigOrMacOSKeychain.cache.clear?.(),ee()}async function maybeRemoveApiKeyFromMacOSKeychain(){try{await N()}catch(e){J(e)}}export function saveOAuthTokensIfNeeded(e,t){if(!P(e.scopes))return a("tengu_oauth_tokens_not_claude_ai",{}),{success:!0};if(!e.refreshToken||!e.expiresAt)return a("tengu_oauth_tokens_inference_only",{}),{success:!0};const r=Q(),n=r.name;try{const o=r.read()||{},s=o.claudeAiOauth,i=t??_("claude"),c={accessToken:e.accessToken,refreshToken:e.refreshToken,expiresAt:e.expiresAt,scopes:e.scopes,subscriptionType:e.subscriptionType??s?.subscriptionType??null,rateLimitTier:e.rateLimitTier??s?.rateLimitTier??null};i&&(o.providerProfileOauth={...o.providerProfileOauth??{},[i]:c});const u=r.update(o);return u.success?a("tengu_oauth_tokens_saved",{storageBackend:n}):a("tengu_oauth_tokens_save_failed",{storageBackend:n}),getClaudeAIOAuthTokens.cache?.clear?.(),L(),le(),u}catch(e){return J(e),a("tengu_oauth_tokens_save_exception",{storageBackend:n,error:W(e)}),{success:!1,warning:"Failed to save OAuth tokens"}}}export function saveOpenAIOAuthTokens(e,t){const r=Q(),n=r.name;try{const o=r.read()||{},s=t??_("openai"),i={accessToken:e.accessToken,refreshToken:e.refreshToken,expiresAt:e.expiresAt,scopes:e.scopes,subscriptionType:e.subscriptionType??null,rateLimitTier:e.rateLimitTier??null};o.openAiOauth=i,s&&(o.providerProfileOauth={...o.providerProfileOauth??{},[s]:i});const c=r.update(o);return c.success?a("tengu_openai_oauth_tokens_saved",{storageBackend:n}):a("tengu_openai_oauth_tokens_save_failed",{storageBackend:n}),getOpenAIOAuthTokens.cache?.clear?.(),L(),le(),c}catch(e){return J(e),a("tengu_openai_oauth_tokens_save_exception",{storageBackend:n,error:W(e)}),{success:!1,warning:"Failed to save OpenAI OAuth tokens"}}}export function getClaudeAIOAuthTokens(){if(B())return null;const e=process.env.CONTEXT_CODE_OAUTH_TOKEN??process.env.CLAUDE_CODE_OAUTH_TOKEN;if(isManagedOAuthContext()&&e)return{accessToken:e,refreshToken:null,expiresAt:null,scopes:["user:inference"],subscriptionType:null,rateLimitTier:null};const t=isManagedOAuthContext()?w():null;if(t)return{accessToken:t,refreshToken:null,expiresAt:null,scopes:["user:inference"],subscriptionType:null,rateLimitTier:null};try{const e=getStoredProviderOAuthTokens("claude",_("claude"));return e?.accessToken?e:null}catch(e){return J(e),null}}export function getOpenAIOAuthTokens(){if(B())return null;if(process.env.OPENAI_OAUTH_TOKEN)return{accessToken:process.env.OPENAI_OAUTH_TOKEN,refreshToken:null,expiresAt:null,scopes:["responses:inference"],subscriptionType:null,rateLimitTier:null};try{const e=getStoredProviderOAuthTokens("openai",_("openai"));return e?.accessToken?e:null}catch(e){return J(e),null}}export function getOpenAIAccessToken(){return process.env.OPENAI_API_KEY||process.env.OPENAI_API_TOKEN||getStoredProviderApiKey("openai",_("openai"))||getOpenAIOAuthTokens()?.accessToken||null}export function getOpenRouterAccessToken(){return process.env.OPENROUTER_API_KEY||process.env.OPENROUTER_API_TOKEN||getStoredProviderApiKey("openrouter",_("openrouter"))||null}export async function checkGeminiGoogleCredentialsValid(){try{const e=await getGeminiGoogleAuthHeaders(),t=process.env.GEMINI_GOOGLE_PROJECT_ID?.trim()||void 0,r=fetch("https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist",{method:"POST",headers:e,body:JSON.stringify({cloudaicompanionProject:t,metadata:{ideType:"IDE_UNSPECIFIED",platform:"PLATFORM_UNSPECIFIED",pluginType:"GEMINI",duetProject:t},mode:"HEALTH_CHECK"})}).then(e=>{if(!e.ok)throw new Error(`Gemini credentials check failed: ${e.status}`)}),n=ue(5e3).then(()=>{throw new GcpCredentialsTimeoutError("Gemini credentials check timed out")});return await Promise.race([r,n]),!0}catch{return!1}}export function getGeminiGoogleOAuthTokens(){try{const e=_("gemini-google"),t=Q().read(),r=e?t?.providerProfileOauth?.[e]:null;if(r?.accessToken)return r;const n=Object.entries(t?.providerProfileOauth??{}).find(([e,t])=>e.startsWith("gemini-google/")&&"object"==typeof t&&null!==t&&"string"==typeof t.accessToken&&t.accessToken.trim())?.[1];return n?.accessToken?n:null}catch{return null}}export function saveGeminiGoogleOAuthTokens(e){const t=Q(),r=t.name;try{const n=t.read()||{},o=_("gemini-google")??g("gemini-google").id,s={accessToken:e.accessToken,refreshToken:e.refreshToken,expiresAt:e.expiresAt,scopes:e.scopes,subscriptionType:null,rateLimitTier:null,projectId:e.projectId};o&&(n.providerProfileOauth={...n.providerProfileOauth??{},[o]:s});const i=t.update(n);return a(i.success?"tengu_gemini_google_oauth_tokens_saved":"tengu_gemini_google_oauth_tokens_save_failed",{storageBackend:r}),i}catch(e){return J(e),a("tengu_gemini_google_oauth_tokens_save_exception",{storageBackend:r,error:W(e)}),{success:!1,warning:"Failed to save Gemini OAuth tokens"}}}export function getCopilotOAuthTokens(){try{const e=_("copilot"),t=Q().read(),r=e?t?.providerProfileOauth?.[e]:null;if(r?.githubToken||r?.accessToken)return r;const n=Object.entries(t?.providerProfileOauth??{}).find(([e,t])=>e.startsWith("copilot/")&&"object"==typeof t&&null!==t&&("string"==typeof t.githubToken||"string"==typeof t.accessToken))?.[1];return n?.githubToken||n?.accessToken?n:null}catch{return null}}export function saveCopilotOAuthTokens(e){const t=Q(),r=t.name;try{const n=t.read()||{},o=_("copilot")??g("copilot").id,s={accessToken:e.accessToken,refreshToken:e.refreshToken,expiresAt:e.expiresAt,scopes:e.scopes,subscriptionType:null,rateLimitTier:null,githubToken:e.githubToken};o&&(n.providerProfileOauth={...n.providerProfileOauth??{},[o]:s});const i=t.update(n);return a(i.success?"tengu_copilot_oauth_tokens_saved":"tengu_copilot_oauth_tokens_save_failed",{storageBackend:r}),i}catch(e){return J(e),a("tengu_copilot_oauth_tokens_save_exception",{storageBackend:r,error:W(e)}),{success:!1,warning:"Failed to save Copilot OAuth tokens"}}}export async function checkAndRefreshCopilotTokenIfNeeded(){const e=getCopilotOAuthTokens();if(!e)return null;const t=e.githubToken||e.accessToken;if(!t)return e;if(e.accessToken&&e.accessToken!==e.githubToken&&e.expiresAt&&e.expiresAt>Date.now()+6e4)return e;try{const r=await fetch("https://api.github.com/copilot_internal/v2/token",{method:"GET",headers:{Authorization:`token ${t}`,"User-Agent":"ContextCode/1.0",Accept:"application/json"}});if(!r.ok)return e;const n=await r.json(),o=n.expires_at?1e3*n.expires_at:Date.now()+15e5,s={...e,accessToken:n.token,githubToken:t,expiresAt:o};return saveCopilotOAuthTokens(s),s}catch{return e}}export function getCopilotAccessToken(){const e=process.env.GITHUB_COPILOT_TOKEN||process.env.COPILOT_OAUTH_TOKEN;if(e)return e;const t=getCopilotOAuthTokens();return t?.accessToken||t?.githubToken||null}function quoteShellArg(e){return`"${e.replace(/"/g,'\\"')}"`}export function getGeminiGoogleAuthCommand(){const e=process.env.GEMINI_OAUTH_CLIENT_SECRET_FILE||process.env.GOOGLE_OAUTH_CLIENT_SECRET_FILE,t=ge.join(",");return`gcloud auth application-default login${e?` --client-id-file=${quoteShellArg(e)}`:""} --scopes=${quoteShellArg(t)}`}export async function refreshGeminiGoogleAuth(){return refreshGcpAuth(getGeminiGoogleAuthCommand())}export function getGeminiApiAccessToken(){return process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||getStoredProviderApiKey("gemini-api",_("gemini-api"))||null}export async function getGeminiGoogleAuthHeaders(){const e=process.env.GEMINI_OAUTH_TOKEN||process.env.GOOGLE_OAUTH_ACCESS_TOKEN,t={"Content-Type":"application/json"};if(e)t.Authorization=`Bearer ${e}`;else{const e=await async function(){const e=getGeminiGoogleOAuthTokens();if(!e?.refreshToken)return e;if(e.expiresAt&&e.expiresAt>Date.now()+6e4)return e;const t=await fetch(A,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",refresh_token:e.refreshToken,client_id:u,client_secret:p})});if(!t.ok)return e;const r=await t.json(),n={...e,accessToken:r.access_token,expiresAt:r.expires_in?Date.now()+1e3*r.expires_in:e.expiresAt,scopes:r.scope?.split(/\s+/).filter(Boolean)??e.scopes};return saveGeminiGoogleOAuthTokens(n),n}();if(e?.accessToken){t.Authorization=`Bearer ${e.accessToken}`;const r=process.env.GEMINI_GOOGLE_PROJECT_ID?.trim();r&&(t["x-goog-user-project"]=r)}else{const{GoogleAuth:e}=await import("google-auth-library"),r=new e({scopes:ge}),n=await r.getClient(),o=await n.getRequestHeaders();if("function"==typeof o.forEach)o.forEach((e,r)=>{t[r]=e});else for(const[e,r]of Object.entries(o))Array.isArray(r)?t[e]=r.map(String).join(", "):null!=r&&(t[e]=String(r))}}const r=process.env.GEMINI_GOOGLE_PROJECT_ID?.trim()||void 0;return r&&(t["x-goog-user-project"]=r),t}export function getZAIAccessToken(){return process.env.ZAI_API_KEY||getStoredProviderApiKey("zai",_("zai"))||null}export function getMiniMaxAccessToken(){return process.env.MINIMAX_API_KEY||getStoredProviderApiKey("minimax",_("minimax"))||null}export function getNvidiaAccessToken(){return process.env.NVIDIA_API_KEY||getStoredProviderApiKey("nvidia",_("nvidia"))||null}export function getDeepSeekAccessToken(){return process.env.DEEPSEEK_API_KEY||getStoredProviderApiKey("deepseek",_("deepseek"))||null}export function getXaiAccessToken(){return process.env.XAI_API_KEY||getStoredProviderApiKey("xai",_("xai"))||null}export function getOllamaAccessToken(){return"ollama"}export function getOllamaCloudAccessToken(){return process.env.OLLAMA_API_KEY||getStoredProviderApiKey("ollama-cloud",_("ollama-cloud"))||null}export function getOpenAICompatibleAccessToken(e=h()){switch(e){case"openrouter":return getOpenRouterAccessToken();case"gemini-api":return getGeminiApiAccessToken();case"gemini-google":return process.env.GEMINI_OAUTH_TOKEN||process.env.GOOGLE_OAUTH_ACCESS_TOKEN||null;case"zai":return getZAIAccessToken();case"minimax":return getMiniMaxAccessToken();case"nvidia":return getNvidiaAccessToken();case"deepseek":return getDeepSeekAccessToken();case"xai":return getXaiAccessToken();case"copilot":return getCopilotAccessToken();case"gmi":case"novita":case"stepfun":case"huggingface":case"opencode-zen":case"arcee":case"alibaba":case"kimi":{const t=Ae[e];return(t?process.env[t]:void 0)||getStoredProviderApiKey(e,_(e))||null}case"ollama":return getOllamaAccessToken();case"ollama-cloud":return getOllamaCloudAccessToken();case"custom-openai":return process.env.CUSTOM_OPENAI_API_KEY||getStoredProviderApiKey("custom-openai",_("custom-openai"))||null;case"custom-anthropic":return process.env.CUSTOM_ANTHROPIC_API_KEY||getStoredProviderApiKey("custom-anthropic",_("custom-anthropic"))||null;default:return getOpenAIAccessToken()}}export async function getOpenAIOAuthTokensAsync(){if(B())return null;if(process.env.OPENAI_OAUTH_TOKEN)return getOpenAIOAuthTokens();try{const e=Q(),t=await e.readAsync(),r=_("openai"),n=r&&t?.providerProfileOauth?.[r]||(r&&!O("openai",r)?null:t?.openAiOauth);return n?.accessToken?n:null}catch(e){return J(e),null}}export function clearOAuthTokenCache(){getClaudeAIOAuthTokens.cache?.clear?.(),getOpenAIOAuthTokens.cache?.clear?.(),re()}let Te=0;async function invalidateOAuthCacheIfDiskChanged(){try{const e="sqlite"===Q().name?ie():se(),{mtimeMs:t}=await s(e);t!==Te&&(Te=t,clearOAuthTokenCache())}catch{getClaudeAIOAuthTokens.cache?.clear?.(),getOpenAIOAuthTokens.cache?.clear?.()}}const Ee=new Map;export function handleOAuth401Error(e){const t=Ee.get(e);if(t)return t;const r=async function(e){clearOAuthTokenCache();const t=await getClaudeAIOAuthTokensAsync();if(!t?.refreshToken)return!1;if(t.accessToken!==e)return a("tengu_oauth_401_recovered_from_keychain",{}),!0;return checkAndRefreshOAuthTokenIfNeeded(0,!0)}(e).finally(()=>{Ee.delete(e)});return Ee.set(e,r),r}export async function handleOpenAIOAuth401Error(e){clearOAuthTokenCache();const t=await getOpenAIOAuthTokensAsync();return!!t?.refreshToken&&(t.accessToken!==e?(a("tengu_openai_oauth_401_recovered_from_keychain",{}),!0):checkAndRefreshOpenAIOAuthTokenIfNeeded(0,!0))}export async function getClaudeAIOAuthTokensAsync(){if(B())return null;if(isManagedOAuthContext()&&(process.env.CONTEXT_CODE_OAUTH_TOKEN||process.env.CLAUDE_CODE_OAUTH_TOKEN||w()))return getClaudeAIOAuthTokens();try{const e=Q(),t=await e.readAsync(),r=_("claude"),n=r&&t?.providerProfileOauth?.[r]||(r&&!O("claude",r)?null:t?.claudeAiOauth);return n?.accessToken?n:null}catch(e){return J(e),null}}let me=null,ke=null;export function checkAndRefreshOAuthTokenIfNeeded(e=0,t=!1){if(0===e&&!t){if(me)return me;const r=checkAndRefreshOAuthTokenIfNeededImpl(e,t);return me=r.finally(()=>{me=null}),me}return checkAndRefreshOAuthTokenIfNeededImpl(e,t)}export function checkAndRefreshOpenAIOAuthTokenIfNeeded(e=0,t=!1){if(0===e&&!t){if(ke)return ke;const r=checkAndRefreshOpenAIOAuthTokenIfNeededImpl(e,t);return ke=r.finally(()=>{ke=null}),ke}return checkAndRefreshOpenAIOAuthTokenIfNeededImpl(e,t)}async function checkAndRefreshOAuthTokenIfNeededImpl(e,t){await invalidateOAuthCacheIfDiskChanged();const r=getClaudeAIOAuthTokens();if(!(t||r?.refreshToken&&v(r.expiresAt)))return!1;if(!r?.refreshToken)return!1;if(!P(r.scopes))return!1;getClaudeAIOAuthTokens.cache?.clear?.(),re();const n=await getClaudeAIOAuthTokensAsync();if(!n?.refreshToken||!v(n.expiresAt))return!1;const s=$();let i;await o(s,{recursive:!0});try{a("tengu_oauth_token_refresh_lock_acquiring",{}),i=await V.lock(s),a("tengu_oauth_token_refresh_lock_acquired",{})}catch(r){return"ELOCKED"===r.code?e<5?(a("tengu_oauth_token_refresh_lock_retry",{retryCount:e+1}),await ue(1e3+1e3*Math.random()),checkAndRefreshOAuthTokenIfNeededImpl(e+1,t)):(a("tengu_oauth_token_refresh_lock_retry_limit_reached",{maxRetries:5}),!1):(J(r),a("tengu_oauth_token_refresh_lock_error",{error:W(r)}),!1)}try{getClaudeAIOAuthTokens.cache?.clear?.(),re();const e=await getClaudeAIOAuthTokensAsync();if(!e?.refreshToken||!v(e.expiresAt))return a("tengu_oauth_token_refresh_race_resolved",{}),!1;a("tengu_oauth_token_refresh_starting",{});return saveOAuthTokensIfNeeded(await K(e.refreshToken,{scopes:P(e.scopes)?void 0:e.scopes})),getClaudeAIOAuthTokens.cache?.clear?.(),re(),!0}catch(e){J(e),getClaudeAIOAuthTokens.cache?.clear?.(),re();const t=await getClaudeAIOAuthTokensAsync();return!(!t||v(t.expiresAt))&&(a("tengu_oauth_token_refresh_race_recovered",{}),!0)}finally{a("tengu_oauth_token_refresh_lock_releasing",{}),await i(),a("tengu_oauth_token_refresh_lock_released",{})}}async function checkAndRefreshOpenAIOAuthTokenIfNeededImpl(e,t){await invalidateOAuthCacheIfDiskChanged();const r=getOpenAIOAuthTokens();if(!(t||r?.refreshToken&&v(r.expiresAt)))return!1;if(!r?.refreshToken)return!1;getOpenAIOAuthTokens.cache?.clear?.(),re();const n=await getOpenAIOAuthTokensAsync();if(!n?.refreshToken||!v(n.expiresAt))return!1;const s=$();let i;await o(s,{recursive:!0});try{a("tengu_openai_oauth_token_refresh_lock_acquiring",{}),i=await V.lock(s),a("tengu_openai_oauth_token_refresh_lock_acquired",{})}catch(r){return"ELOCKED"===r.code?e<5?(a("tengu_openai_oauth_token_refresh_lock_retry",{retryCount:e+1}),await ue(1e3+1e3*Math.random()),checkAndRefreshOpenAIOAuthTokenIfNeededImpl(e+1,t)):(a("tengu_openai_oauth_token_refresh_lock_retry_limit_reached",{maxRetries:5}),!1):(J(r),!1)}try{getOpenAIOAuthTokens.cache?.clear?.(),re();const e=await getOpenAIOAuthTokensAsync();if(!e?.refreshToken||!v(e.expiresAt))return a("tengu_openai_oauth_token_refresh_race_resolved",{}),!1;a("tengu_openai_oauth_token_refresh_starting",{});return saveOpenAIOAuthTokens(await I(e.refreshToken,{scopes:e.scopes})),getOpenAIOAuthTokens.cache?.clear?.(),re(),!0}catch(e){J(e),getOpenAIOAuthTokens.cache?.clear?.(),re();const t=await getOpenAIOAuthTokensAsync();return!(!t||v(t.expiresAt))&&(a("tengu_openai_oauth_token_refresh_race_recovered",{}),!0)}finally{a("tengu_openai_oauth_token_refresh_lock_releasing",{}),await i(),a("tengu_openai_oauth_token_refresh_lock_released",{})}}export function isClaudeAISubscriber(){return!!isAnthropicAuthEnabled()&&P(getClaudeAIOAuthTokens()?.scopes)}export function hasProfileScope(){return getClaudeAIOAuthTokens()?.scopes?.includes(c)??!1}export function is1PApiCustomer(){return!(X(process.env.CONTEXT_CODE_USE_BEDROCK)||X(process.env.CLAUDE_CODE_USE_BEDROCK)||X(process.env.CONTEXT_CODE_USE_VERTEX)||X(process.env.CLAUDE_CODE_USE_VERTEX)||X(process.env.CONTEXT_CODE_USE_FOUNDRY)||X(process.env.CLAUDE_CODE_USE_FOUNDRY)||f(h()))&&!isClaudeAISubscriber()}export function getOauthAccountInfo(){return isAnthropicAuthEnabled()?G().oauthAccount:void 0}export function isOverageProvisioningAllowed(){const e=getOauthAccountInfo(),t=e?.billingType;return!(!isClaudeAISubscriber()||!t)&&("stripe_subscription"===t||"stripe_subscription_contracted"===t||"apple_subscription"===t||"google_play_subscription"===t)}export function hasOpusAccess(){const e=getSubscriptionType();return"max"===e||"enterprise"===e||"team"===e||"pro"===e||null===e}export function getSubscriptionType(){if(C())return y();if(!isAnthropicAuthEnabled())return null;const e=getClaudeAIOAuthTokens();return e?e.subscriptionType??null:null}export function isMaxSubscriber(){return"max"===getSubscriptionType()}export function isTeamSubscriber(){return"team"===getSubscriptionType()}export function isTeamPremiumSubscriber(){return"team"===getSubscriptionType()&&"default_claude_max_5x"===getRateLimitTier()}export function isEnterpriseSubscriber(){return"enterprise"===getSubscriptionType()}export function isProSubscriber(){return"pro"===getSubscriptionType()}export function getRateLimitTier(){if(!isAnthropicAuthEnabled())return null;const e=getClaudeAIOAuthTokens();return e?e.rateLimitTier??null:null}export function getSubscriptionName(){switch(getSubscriptionType()){case"enterprise":return"Context Empresarial";case"team":return"Context Equipo";case"max":return"Context Max";case"pro":return"Context Pro";default:return"Context API"}}export function isUsing3PServices(){return!!(X(process.env.CONTEXT_CODE_USE_BEDROCK)||X(process.env.CLAUDE_CODE_USE_BEDROCK)||X(process.env.CONTEXT_CODE_USE_VERTEX)||X(process.env.CLAUDE_CODE_USE_VERTEX)||X(process.env.CONTEXT_CODE_USE_FOUNDRY)||X(process.env.CLAUDE_CODE_USE_FOUNDRY)||f(h()))}function getConfiguredOtelHeadersHelper(){return(ce()||{}).otelHeadersHelper}export function isOtelHeadersHelperFromProjectOrLocalSettings(){const e=getConfiguredOtelHeadersHelper();if(!e)return!1;const t=ae("projectSettings"),r=ae("localSettings");return t?.otelHeadersHelper===e||r?.otelHeadersHelper===e}let ye=null,Ce=0;const ve=174e4;export function getOtelHeadersFromHelper(){const e=getConfiguredOtelHeadersHelper();if(!e)return{};const t=parseInt(process.env.CONTEXT_CODE_OTEL_HEADERS_HELPER_DEBOUNCE_MS||process.env.CLAUDE_CODE_OTEL_HEADERS_HELPER_DEBOUNCE_MS||ve.toString());if(ye&&Date.now()-Ce<t)return ye;if(isOtelHeadersHelperFromProjectOrLocalSettings()){if(!j())return{}}try{const t=q(e,{timeout:3e4})?.toString().trim();if(!t)throw new Error("otelHeadersHelper did not return a valid value");const r=pe(t);if("object"!=typeof r||null===r||Array.isArray(r))throw new Error("otelHeadersHelper must return a JSON object with string key-value pairs");for(const[e,t]of Object.entries(r))if("string"!=typeof t)throw new Error(`otelHeadersHelper returned non-string value for key "${e}": ${typeof t}`);return ye=r,Ce=Date.now(),ye}catch(e){throw J(new Error(`Error getting OpenTelemetry headers from otelHeadersHelper (in settings): ${W(e)}`)),e}}export function isConsumerSubscriber(){const e=getSubscriptionType();return isClaudeAISubscriber()&&null!==e&&("max"===(t=e)||"pro"===t);var t}export function getAccountInformation(){if("firstParty"!==h())return;const{source:e}=getAuthTokenSource(),t={};"CLAUDE_CODE_OAUTH_TOKEN"===e||"CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR"===e?t.tokenSource=e:isClaudeAISubscriber()?t.subscription=getSubscriptionName():t.tokenSource=e;const{key:r,source:n}=getAnthropicApiKeyWithSource();if(r&&(t.apiKeySource=n),"claude.ai"===e||"/login managed key"===n){const e=getOauthAccountInfo()?.organizationName;e&&(t.organization=e)}const o=getOauthAccountInfo()?.emailAddress;return"claude.ai"!==e&&"/login managed key"!==n||!o||(t.email=o),t}export async function validateForceLoginOrg(){if(process.env.ANTHROPIC_UNIX_SOCKET)return{valid:!0};if(!isAnthropicAuthEnabled())return{valid:!0};const e=ae("policySettings")?.forceLoginOrgUUID;if(!e)return{valid:!0};await checkAndRefreshOAuthTokenIfNeeded();const t=getClaudeAIOAuthTokens();if(!t)return{valid:!0};const{source:r}=getAuthTokenSource(),n="CLAUDE_CODE_OAUTH_TOKEN"===r||"CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR"===r,o=await S(t.accessToken);if(!o)return{valid:!1,message:`Unable to verify organization for the current authentication token.\nThis machine requires organization ${e} but the profile could not be fetched.\nThis may be a network error, or the token may lack the user:profile scope required for\nverification (tokens from 'context setup-token' do not include this scope).\nTry again, or obtain a full-scope token via 'context auth login'.`};const s=o.organization.uuid;if(s===e)return{valid:!0};if(n){return{valid:!1,message:`The ${"CLAUDE_CODE_OAUTH_TOKEN"===r?"CLAUDE_CODE_OAUTH_TOKEN":"CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR"} environment variable provides a token for a\ndifferent organization than required by this machine's managed settings.\n\nRequired organization: ${e}\nToken organization: ${s}\n\nRemove the environment variable or obtain a token for the correct organization.`}}return{valid:!1,message:`Your authentication token belongs to organization ${s},\nbut this machine requires organization ${e}.\n\nPlease log in with the correct organization: context auth login`}}class GcpCredentialsTimeoutError extends Error{}
1
+ import{MACRO as e}from"../recovery/bunBundleShim.js";import t from"chalk";import{exec as r}from"child_process";import{execa as n}from"execa";import{mkdir as o,stat as s}from"fs/promises";import i from"lodash-es/memoize.js";import{CLAUDE_AI_PROFILE_SCOPE as c}from"../constants/oauth.js";import{logEvent as a}from"../services/analytics/index.js";import{GEMINI_CLI_OAUTH_CLIENT_ID as u,GEMINI_CLI_OAUTH_CLIENT_SECRET as p,GEMINI_CLI_OAUTH_SCOPES as l,GEMINI_CLI_OAUTH_TOKEN_URL as A}from"../constants/geminiOAuth.js";import{getModelStrings as d}from"./model/modelStrings.js";import{getAPIProvider as h,isOpenAICompatibleProvider as f}from"./model/providers.js";import{getResolvedProviderProfileId as _,ensureProviderProfile as g,isDefaultProfileId as O,isProfiledProvider as T,resolveProviderProfile as E}from"./model/providerProfiles.js";import{getIsNonInteractiveSession as m,preferThirdPartyAuthentication as k}from"../bootstrap/state.js";import{getMockSubscriptionType as y,shouldUseMockSubscription as C}from"../services/mockRateLimits.js";import{isOAuthTokenExpired as v,refreshOpenAIOAuthToken as I,refreshOAuthToken as K,shouldUseClaudeAIAuth as P}from"../services/oauth/client.js";import{getOauthProfileFromOauthToken as S}from"../services/oauth/getOauthProfile.js";import{getApiKeyFromFileDescriptor as x,getOAuthTokenFromFileDescriptor as w}from"./authFileDescriptor.js";import{maybeRemoveApiKeyFromMacOSKeychainThrows as N,normalizeApiKeyForConfig as R}from"./authPortable.js";import{checkStsCallerIdentity as D,clearAwsIniCache as H,isValidAwsStsOutput as b}from"./aws.js";import{AwsAuthStatusManager as U}from"./awsAuthStatusManager.js";import{clearBetasCaches as L}from"./betas.js";import{checkHasTrustDialogAccepted as j,getGlobalConfig as G,saveGlobalConfig as F}from"./config.js";import{logAntError as M,logForDebugging as Y}from"./debug.js";import{getClaudeConfigHomeDir as $,isBareMode as B,isEnvTruthy as X,isRunningOnHomespace as z}from"./envUtils.js";import{errorMessage as W}from"./errors.js";import{execSyncWithDefaults_DEPRECATED as q}from"./execFileNoThrow.js";import*as V from"./lockfile.js";import{logError as J}from"./log.js";import{memoizeWithTTLAsync as Z}from"./memoize.js";import{getSecureStorage as Q}from"./secureStorage/index.js";import{clearLegacyApiKeyPrefetch as ee,getLegacyApiKeyPrefetchResult as te}from"./secureStorage/keychainPrefetch.js";import{clearKeychainCache as re,getMacOsKeychainStorageServiceName as ne,getUsername as oe}from"./secureStorage/macOsKeychainHelpers.js";import{getLegacyCredentialsFilePath as se,getSecureStorageDbPath as ie}from"./secureStorage/sqliteStorage.js";import{getSettings_DEPRECATED as ce,getSettingsForSource as ae}from"./settings/settings.js";import{sleep as ue}from"./sleep.js";import{jsonParse as pe}from"./slowOperations.js";import{clearToolSchemaCache as le}from"./toolSchemaCache.js";function isManagedOAuthContext(){return X(process.env.CONTEXT_CODE_REMOTE)||X(process.env.CLAUDE_CODE_REMOTE)||"claude-desktop"===process.env.CLAUDE_CODE_ENTRYPOINT}export function isAnthropicAuthEnabled(){if(B())return!1;if(process.env.ANTHROPIC_UNIX_SOCKET)return!(!process.env.CONTEXT_CODE_OAUTH_TOKEN&&!process.env.CLAUDE_CODE_OAUTH_TOKEN);const e=h(),t=X(process.env.CONTEXT_CODE_USE_BEDROCK)||X(process.env.CLAUDE_CODE_USE_BEDROCK)||X(process.env.CONTEXT_CODE_USE_VERTEX)||X(process.env.CLAUDE_CODE_USE_VERTEX)||X(process.env.CONTEXT_CODE_USE_FOUNDRY)||X(process.env.CLAUDE_CODE_USE_FOUNDRY)||f(e)||"custom-anthropic"===e,r=(ce()||{}).apiKeyHelper,n=process.env.ANTHROPIC_AUTH_TOKEN||r||process.env.CONTEXT_CODE_API_KEY_FILE_DESCRIPTOR||process.env.CLAUDE_CODE_API_KEY_FILE_DESCRIPTOR,{source:o}=getAnthropicApiKeyWithSource({skipRetrievingKeyFromApiKeyHelper:!0}),s="ANTHROPIC_API_KEY"===o||"apiKeyHelper"===o;return!(t||n&&!isManagedOAuthContext()||s&&!isManagedOAuthContext())}export function getAuthTokenSource(){const e=h();if(f(e))return{source:e,hasToken:Boolean(getOpenAICompatibleAccessToken(e))};if(B())return getConfiguredApiKeyHelper()?{source:"apiKeyHelper",hasToken:!0}:{source:"none",hasToken:!1};if(process.env.ANTHROPIC_AUTH_TOKEN&&!isManagedOAuthContext())return{source:"ANTHROPIC_AUTH_TOKEN",hasToken:!0};if(isManagedOAuthContext()&&(process.env.CONTEXT_CODE_OAUTH_TOKEN||process.env.CLAUDE_CODE_OAUTH_TOKEN))return{source:"CLAUDE_CODE_OAUTH_TOKEN",hasToken:!0};if(isManagedOAuthContext()?w():null)return process.env.CONTEXT_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR||process.env.CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR?{source:"CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR",hasToken:!0}:{source:"CCR_OAUTH_TOKEN_FILE",hasToken:!0};if(getConfiguredApiKeyHelper()&&!isManagedOAuthContext())return{source:"apiKeyHelper",hasToken:!0};const t=getClaudeAIOAuthTokens();return P(t?.scopes)&&t?.accessToken?{source:"claude.ai",hasToken:!0}:{source:"none",hasToken:!1}}const Ae={gmi:"GMI_API_KEY",novita:"NOVITA_API_KEY",stepfun:"STEPFUN_API_KEY",huggingface:"HF_TOKEN","opencode-zen":"OPENCODE_ZEN_API_KEY",arcee:"ARCEEAI_API_KEY",alibaba:"DASHSCOPE_API_KEY",kimi:"KIMI_API_KEY"};function getProviderOauthStorageKey(e){return"claude"===e?"claudeAiOauth":"openAiOauth"}function shouldUseLegacyProviderOauthFallback(e){return"openai"===e}export function getStoredProviderOAuthTokens(e,t){try{const r=Q().read();if(t){const n=r?.providerProfileOauth?.[t];if(n?.accessToken)return n;if(!O(e,t)&&!shouldUseLegacyProviderOauthFallback(e))return null}if("gemini-google"===e)return null;if(!shouldUseLegacyProviderOauthFallback(e))return null;const n=r?.[getProviderOauthStorageKey(e)];return n?.accessToken?n:null}catch{return null}}export function hasStoredProviderOAuthTokens(e,t){if(t)return Boolean(getStoredProviderOAuthTokens(e,t));try{const t=Q().read(),r=Object.entries(t?.providerProfileOauth??{}).some(([t,r])=>t.startsWith(`${e}/`)&&"object"==typeof r&&null!==r&&"string"==typeof r.accessToken&&r.accessToken.trim());return shouldUseLegacyProviderOauthFallback(e)?Boolean(r||t?.[getProviderOauthStorageKey(e)]?.accessToken):Boolean(r)}catch{return!1}}export async function renameProviderScopedCredentials(e,t){if(!e||!t||e===t)return;const r=Q(),n=r.read()||{},o={...n.providerProfileApiKeys??{}},s={...n.providerProfileOauth??{}};e in o&&(o[t]=o[e],delete o[e]),e in s&&(s[t]=s[e],delete s[e]);if(!r.update({...n,providerProfileApiKeys:o,providerProfileOauth:s}).success)throw new Error("No se pudieron mover las credenciales del perfil.")}export async function removeProviderScopedCredentials(e){if(!e)return;const t=Q(),r=t.read()||{},n={...r.providerProfileApiKeys??{}},o={...r.providerProfileOauth??{}};delete n[e],delete o[e];if(!t.update({...r,providerProfileApiKeys:n,providerProfileOauth:o}).success)throw new Error("No se pudieron eliminar las credenciales del perfil.")}export async function removeAllProviderScopedCredentials(){const e=Q(),t=e.read()||{};if(!e.update({...t,providerProfileApiKeys:{},providerProfileOauth:{}}).success)throw new Error("No se pudieron eliminar las credenciales scoped de perfiles.")}export function getAnthropicApiKey(){const{key:e}=getAnthropicApiKeyWithSource();return e}export function hasAnthropicApiKeyAuth(){const{key:e,source:t}=getAnthropicApiKeyWithSource({skipRetrievingKeyFromApiKeyHelper:!0});return null!==e&&"none"!==t}export function getAnthropicApiKeyWithSource(e={}){if(f(h()))return{key:null,source:"none"};if(B())return process.env.ANTHROPIC_API_KEY?{key:process.env.ANTHROPIC_API_KEY,source:"ANTHROPIC_API_KEY"}:getConfiguredApiKeyHelper()?{key:e.skipRetrievingKeyFromApiKeyHelper?null:getApiKeyFromApiKeyHelperCached(),source:"apiKeyHelper"}:{key:null,source:"none"};const t=z()?void 0:process.env.ANTHROPIC_API_KEY;if(k()&&t)return{key:t,source:"ANTHROPIC_API_KEY"};if(X(process.env.CI)||"test"===process.env.NODE_ENV){const e=x();if(e)return{key:e,source:"ANTHROPIC_API_KEY"};if(!(t||process.env.CONTEXT_CODE_OAUTH_TOKEN||process.env.CLAUDE_CODE_OAUTH_TOKEN||process.env.CONTEXT_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR||process.env.CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR))throw new Error("ANTHROPIC_API_KEY or CONTEXT_CODE_OAUTH_TOKEN (legacy: CLAUDE_CODE_OAUTH_TOKEN) env var is required");return t?{key:t,source:"ANTHROPIC_API_KEY"}:{key:null,source:"none"}}if(t&&G().customApiKeyResponses?.approved?.includes(R(t)))return{key:t,source:"ANTHROPIC_API_KEY"};const r=x();if(r)return{key:r,source:"ANTHROPIC_API_KEY"};if(getConfiguredApiKeyHelper())return e.skipRetrievingKeyFromApiKeyHelper?{key:null,source:"apiKeyHelper"}:{key:getApiKeyFromApiKeyHelperCached(),source:"apiKeyHelper"};const n=getApiKeyFromConfigOrMacOSKeychain();return n||{key:null,source:"none"}}export function getConfiguredApiKeyHelper(){if(B())return ae("flagSettings")?.apiKeyHelper;return(ce()||{}).apiKeyHelper}function isApiKeyHelperFromProjectOrLocalSettings(){const e=getConfiguredApiKeyHelper();if(!e)return!1;const t=ae("projectSettings"),r=ae("localSettings");return t?.apiKeyHelper===e||r?.apiKeyHelper===e}function getConfiguredAwsAuthRefresh(){return(ce()||{}).awsAuthRefresh}export function isAwsAuthRefreshFromProjectSettings(){const e=getConfiguredAwsAuthRefresh();if(!e)return!1;const t=ae("projectSettings"),r=ae("localSettings");return t?.awsAuthRefresh===e||r?.awsAuthRefresh===e}function getConfiguredAwsCredentialExport(){return(ce()||{}).awsCredentialExport}export function isAwsCredentialExportFromProjectSettings(){const e=getConfiguredAwsCredentialExport();if(!e)return!1;const t=ae("projectSettings"),r=ae("localSettings");return t?.awsCredentialExport===e||r?.awsCredentialExport===e}export function calculateApiKeyHelperTTL(){const e=process.env.CONTEXT_CODE_API_KEY_HELPER_TTL_MS??process.env.CLAUDE_CODE_API_KEY_HELPER_TTL_MS;if(e){const t=parseInt(e,10);if(!Number.isNaN(t)&&t>=0)return t;Y(`Found CLAUDE_CODE_API_KEY_HELPER_TTL_MS env var, but it was not a valid number. Got ${e}`,{level:"error"})}return 3e5}let de=null,he=null,fe=0;export function getApiKeyHelperElapsedMs(){const e=he?.startedAt;return e?Date.now()-e:0}export async function getApiKeyFromApiKeyHelper(e){if(!getConfiguredApiKeyHelper())return null;const t=calculateApiKeyHelperTTL();return de?(Date.now()-de.timestamp<t||he||(he={promise:_runAndCache(e,!1,fe),startedAt:null}),de.value):(he||(he={promise:_runAndCache(e,!0,fe),startedAt:Date.now()}),he.promise)}async function _runAndCache(r,o,s){try{const t=await async function(t){const r=getConfiguredApiKeyHelper();if(!r)return null;if(isApiKeyHelperFromProjectOrLocalSettings()){if(!j()&&!t){const t=new Error(`Security: apiKeyHelper executed before workspace trust is confirmed. If you see this message, post in ${e.FEEDBACK_CHANNEL}.`);return M("apiKeyHelper invoked before trust check",t),a("tengu_apiKeyHelper_missing_trust11",{}),null}}const o=await n(r,{shell:!0,timeout:6e5,reject:!1});if(o.failed){const e=o.timedOut?"timed out":`exited ${o.exitCode}`,t=o.stderr?.trim();throw new Error(t?`${e}: ${t}`:e)}const s=o.stdout?.trim();if(!s)throw new Error("did not return a value");return s}(r);return s!==fe||null!==t&&(de={value:t,timestamp:Date.now()}),t}catch(e){if(s!==fe)return" ";const r=e instanceof Error?e.message:String(e);return console.error(t.red(`apiKeyHelper failed: ${r}`)),Y(`Error getting API key from apiKeyHelper: ${r}`,{level:"error"}),!o&&de&&" "!==de.value?(de={...de,timestamp:Date.now()},de.value):(de={value:" ",timestamp:Date.now()}," ")}finally{s===fe&&(he=null)}}export function getApiKeyFromApiKeyHelperCached(){return de?.value??null}export function clearApiKeyHelperCache(){fe++,de=null,he=null}export function prefetchApiKeyFromApiKeyHelperIfSafe(e){isApiKeyHelperFromProjectOrLocalSettings()&&!j()||getApiKeyFromApiKeyHelper(e)}const _e=18e4;export function refreshAwsAuth(e){Y("Running AWS auth refresh command");const n=U.getInstance();return n.startAuthentication(),new Promise(o=>{const s=r(e,{timeout:_e});s.stdout.on("data",e=>{const t=e.toString().trim();t&&(n.addOutput(t),Y(t,{level:"debug"}))}),s.stderr.on("data",e=>{const t=e.toString().trim();t&&(n.setError(t),Y(t,{level:"error"}))}),s.on("close",(e,r)=>{if(0===e)Y("AWS auth refresh completed successfully"),n.endAuthentication(!0),o(!0);else{const e="SIGTERM"===r?t.red("AWS auth refresh timed out after 3 minutes. Run your auth command manually in a separate terminal."):t.red("Error running awsAuthRefresh (in settings or ~/.context.json):");console.error(e),n.endAuthentication(!1),o(!1)}})})}export const refreshAndGetAwsCredentials=Z(async()=>{const r=await async function(){const t=getConfiguredAwsAuthRefresh();if(!t)return!1;if(isAwsAuthRefreshFromProjectSettings()&&!j()&&!m()){const t=new Error(`Security: awsAuthRefresh executed before workspace trust is confirmed. If you see this message, post in ${e.FEEDBACK_CHANNEL}.`);return M("awsAuthRefresh invoked before trust check",t),a("tengu_awsAuthRefresh_missing_trust",{}),!1}try{return Y("Fetching AWS caller identity for AWS auth refresh command"),await D(),Y("Fetched AWS caller identity, skipping AWS auth refresh command"),!1}catch{return refreshAwsAuth(t)}}(),o=await async function(){const r=getConfiguredAwsCredentialExport();if(!r)return null;if(isAwsCredentialExportFromProjectSettings()&&!j()&&!m()){const t=new Error(`Security: awsCredentialExport executed before workspace trust is confirmed. If you see this message, post in ${e.FEEDBACK_CHANNEL}.`);return M("awsCredentialExport invoked before trust check",t),a("tengu_awsCredentialExport_missing_trust",{}),null}try{return Y("Fetching AWS caller identity for credential export command"),await D(),Y("Fetched AWS caller identity, skipping AWS credential export command"),null}catch{try{Y("Running AWS credential export command");const e=await n(r,{shell:!0,reject:!1});if(0!==e.exitCode||!e.stdout)throw new Error("awsCredentialExport did not return a valid value");const t=pe(e.stdout.trim());if(!b(t))throw new Error("awsCredentialExport did not return valid AWS STS output structure");return Y("AWS credentials retrieved from awsCredentialExport"),{accessKeyId:t.Credentials.AccessKeyId,secretAccessKey:t.Credentials.SecretAccessKey,sessionToken:t.Credentials.SessionToken}}catch(e){const r=t.red("Error getting AWS credentials from awsCredentialExport (in settings or ~/.context.json):");return e instanceof Error?console.error(r,e.message):console.error(r,e),null}}}();return(r||o)&&await H(),o},36e5);export function clearAwsCredentialsCache(){refreshAndGetAwsCredentials.cache.clear()}function getConfiguredGcpAuthRefresh(){return(ce()||{}).gcpAuthRefresh}export function isGcpAuthRefreshFromProjectSettings(){const e=getConfiguredGcpAuthRefresh();if(!e)return!1;const t=ae("projectSettings"),r=ae("localSettings");return t?.gcpAuthRefresh===e||r?.gcpAuthRefresh===e}const ge=l;export async function checkGcpCredentialsValid(){try{const{GoogleAuth:e}=await import("google-auth-library"),t=new e({scopes:["https://www.googleapis.com/auth/cloud-platform"]}),r=(async()=>{const e=await t.getClient();await e.getAccessToken()})(),n=ue(5e3).then(()=>{throw new GcpCredentialsTimeoutError("GCP credentials check timed out")});return await Promise.race([r,n]),!0}catch{return!1}}const Oe=18e4;export function refreshGcpAuth(e){Y("Running GCP auth refresh command");const n=U.getInstance();return n.startAuthentication(),new Promise(o=>{const s=r(e,{timeout:Oe});s.stdout.on("data",e=>{const t=e.toString().trim();t&&(n.addOutput(t),Y(t,{level:"debug"}))}),s.stderr.on("data",e=>{const t=e.toString().trim();t&&(n.setError(t),Y(t,{level:"error"}))}),s.on("close",(e,r)=>{if(0===e)Y("GCP auth refresh completed successfully"),n.endAuthentication(!0),o(!0);else{const e="SIGTERM"===r?t.red("GCP auth refresh timed out after 3 minutes. Run your auth command manually in a separate terminal."):t.red("Error running gcpAuthRefresh (in settings or ~/.context.json):");console.error(e),n.endAuthentication(!1),o(!1)}})})}export const refreshGcpCredentialsIfNeeded=Z(async()=>await async function(){const t=getConfiguredGcpAuthRefresh();if(!t)return!1;if(isGcpAuthRefreshFromProjectSettings()&&!j()&&!m()){const t=new Error(`Security: gcpAuthRefresh executed before workspace trust is confirmed. If you see this message, post in ${e.FEEDBACK_CHANNEL}.`);return M("gcpAuthRefresh invoked before trust check",t),a("tengu_gcpAuthRefresh_missing_trust",{}),!1}try{if(Y("Checking GCP credentials validity for auth refresh"),await checkGcpCredentialsValid())return Y("GCP credentials are valid, skipping auth refresh command"),!1}catch{}return refreshGcpAuth(t)}(),36e5);export function clearGcpCredentialsCache(){refreshGcpCredentialsIfNeeded.cache.clear()}export function prefetchGcpCredentialsIfSafe(){if(getConfiguredGcpAuthRefresh()){if(isGcpAuthRefreshFromProjectSettings()){if(!j()&&!m())return}refreshGcpCredentialsIfNeeded()}}export function prefetchAwsCredentialsAndBedRockInfoIfSafe(){const e=getConfiguredAwsAuthRefresh(),t=getConfiguredAwsCredentialExport();if(e||t){if(isAwsAuthRefreshFromProjectSettings()||isAwsCredentialExportFromProjectSettings()){if(!j()&&!m())return}refreshAndGetAwsCredentials(),d()}}export const getApiKeyFromConfigOrMacOSKeychain=i(()=>{if("darwin"===process.platform){const e=te();if(e){if(e.stdout)return{key:e.stdout,source:"/login managed key"}}else{const e=ne();try{const t=q(`security find-generic-password -a $USER -w -s "${e}"`);if(t)return{key:t,source:"/login managed key"}}catch(e){J(e)}}}const e=G();return e.primaryApiKey?{key:e.primaryApiKey,source:"/login managed key"}:null});function isValidApiKey(e){return/^[a-zA-Z0-9-_\.]+$/.test(e)}function getStoredProviderApiKey(e,t){try{const r=Q().read();if(t){const n=r?.providerProfileApiKeys?.[t];if("string"==typeof n&&n.trim())return n;if(!O(e,t))return null}return r?.providerApiKeys?.[e]??null}catch{return null}}export function hasStoredProviderApiKey(e,t){return Boolean(getStoredProviderApiKey(e,t))}export async function saveProviderApiKey(e,t){if(!isValidApiKey(t))throw new Error("Formato de clave API inválido. La clave API solo debe contener caracteres alfanuméricos, guiones, guiones bajos y puntos.");const r=Q(),n=r.read()||{},o=T(e)?E(e,{createIfMissing:!0})?.id??null:null;if(!r.update({...n,providerApiKeys:{...n.providerApiKeys??{},[e]:t},...o?{providerProfileApiKeys:{...n.providerProfileApiKeys??{},[o]:t}}:{}}).success)throw new Error(`Failed to save ${e} API key`)}export async function removeProviderApiKey(e){const t=Q(),r=t.read()||{},n={...r.providerApiKeys??{}};delete n[e];const o={...r.providerProfileApiKeys??{}};if(T(e)){const t=_(e);t&&delete o[t]}if(!t.update({...r,providerApiKeys:n,providerProfileApiKeys:o}).success)throw new Error(`Failed to remove ${e} API key`)}export async function saveApiKey(e){if(!isValidApiKey(e))throw new Error("Formato de clave API inválido. La clave API solo debe contener caracteres alfanuméricos, guiones, guiones bajos y puntos.");await maybeRemoveApiKeyFromMacOSKeychain();let t=!1;if("darwin"===process.platform)try{const r=ne(),o=oe(),s=`add-generic-password -U -a "${o}" -s "${r}" -X "${Buffer.from(e,"utf-8").toString("hex")}"\n`;await n("security",["-i"],{input:s,reject:!1}),a("tengu_api_key_saved_to_keychain",{}),t=!0}catch(e){J(e),a("tengu_api_key_keychain_error",{error:W(e)}),a("tengu_api_key_saved_to_config",{})}else a("tengu_api_key_saved_to_config",{});const r=R(e);F(n=>{const o=n.customApiKeyResponses?.approved??[];return{...n,primaryApiKey:t?n.primaryApiKey:e,customApiKeyResponses:{...n.customApiKeyResponses,approved:o.includes(r)?o:[...o,r],rejected:n.customApiKeyResponses?.rejected??[]}}}),getApiKeyFromConfigOrMacOSKeychain.cache.clear?.(),ee()}export function isCustomApiKeyApproved(e){const t=G(),r=R(e);return t.customApiKeyResponses?.approved?.includes(r)??!1}export async function removeApiKey(){await maybeRemoveApiKeyFromMacOSKeychain(),F(e=>({...e,primaryApiKey:void 0})),getApiKeyFromConfigOrMacOSKeychain.cache.clear?.(),ee()}async function maybeRemoveApiKeyFromMacOSKeychain(){try{await N()}catch(e){J(e)}}export function saveOAuthTokensIfNeeded(e,t){if(!P(e.scopes))return a("tengu_oauth_tokens_not_claude_ai",{}),{success:!0};if(!e.refreshToken||!e.expiresAt)return a("tengu_oauth_tokens_inference_only",{}),{success:!0};const r=Q(),n=r.name;try{const o=r.read()||{},s=o.claudeAiOauth,i=t??_("claude")??E("claude",{createIfMissing:!0})?.id??null,c={accessToken:e.accessToken,refreshToken:e.refreshToken,expiresAt:e.expiresAt,scopes:e.scopes,subscriptionType:e.subscriptionType??s?.subscriptionType??null,rateLimitTier:e.rateLimitTier??s?.rateLimitTier??null};i&&(o.providerProfileOauth={...o.providerProfileOauth??{},[i]:c});const u=r.update(o);return u.success?a("tengu_oauth_tokens_saved",{storageBackend:n}):a("tengu_oauth_tokens_save_failed",{storageBackend:n}),getClaudeAIOAuthTokens.cache?.clear?.(),L(),le(),u}catch(e){return J(e),a("tengu_oauth_tokens_save_exception",{storageBackend:n,error:W(e)}),{success:!1,warning:"Failed to save OAuth tokens"}}}export function saveOpenAIOAuthTokens(e,t){const r=Q(),n=r.name;try{const o=r.read()||{},s=t??_("openai")??E("openai",{createIfMissing:!0})?.id??null,i={accessToken:e.accessToken,refreshToken:e.refreshToken,expiresAt:e.expiresAt,scopes:e.scopes,subscriptionType:e.subscriptionType??null,rateLimitTier:e.rateLimitTier??null};o.openAiOauth=i,s&&(o.providerProfileOauth={...o.providerProfileOauth??{},[s]:i});const c=r.update(o);return c.success?a("tengu_openai_oauth_tokens_saved",{storageBackend:n}):a("tengu_openai_oauth_tokens_save_failed",{storageBackend:n}),getOpenAIOAuthTokens.cache?.clear?.(),L(),le(),c}catch(e){return J(e),a("tengu_openai_oauth_tokens_save_exception",{storageBackend:n,error:W(e)}),{success:!1,warning:"Failed to save OpenAI OAuth tokens"}}}export function getClaudeAIOAuthTokens(){if(B())return null;const e=process.env.CONTEXT_CODE_OAUTH_TOKEN??process.env.CLAUDE_CODE_OAUTH_TOKEN;if(isManagedOAuthContext()&&e)return{accessToken:e,refreshToken:null,expiresAt:null,scopes:["user:inference"],subscriptionType:null,rateLimitTier:null};const t=isManagedOAuthContext()?w():null;if(t)return{accessToken:t,refreshToken:null,expiresAt:null,scopes:["user:inference"],subscriptionType:null,rateLimitTier:null};try{const e=getStoredProviderOAuthTokens("claude",_("claude"));return e?.accessToken?e:null}catch(e){return J(e),null}}export function getOpenAIOAuthTokens(){if(B())return null;if(process.env.OPENAI_OAUTH_TOKEN)return{accessToken:process.env.OPENAI_OAUTH_TOKEN,refreshToken:null,expiresAt:null,scopes:["responses:inference"],subscriptionType:null,rateLimitTier:null};try{const e=getStoredProviderOAuthTokens("openai",_("openai"));return e?.accessToken?e:null}catch(e){return J(e),null}}export function getOpenAIAccessToken(){return process.env.OPENAI_API_KEY||process.env.OPENAI_API_TOKEN||getStoredProviderApiKey("openai",_("openai"))||getOpenAIOAuthTokens()?.accessToken||null}export function getOpenRouterAccessToken(){return process.env.OPENROUTER_API_KEY||process.env.OPENROUTER_API_TOKEN||getStoredProviderApiKey("openrouter",_("openrouter"))||null}export async function checkGeminiGoogleCredentialsValid(){try{const e=await getGeminiGoogleAuthHeaders(),t=process.env.GEMINI_GOOGLE_PROJECT_ID?.trim()||void 0,r=fetch("https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist",{method:"POST",headers:e,body:JSON.stringify({cloudaicompanionProject:t,metadata:{ideType:"IDE_UNSPECIFIED",platform:"PLATFORM_UNSPECIFIED",pluginType:"GEMINI",duetProject:t},mode:"HEALTH_CHECK"})}).then(e=>{if(!e.ok)throw new Error(`Gemini credentials check failed: ${e.status}`)}),n=ue(5e3).then(()=>{throw new GcpCredentialsTimeoutError("Gemini credentials check timed out")});return await Promise.race([r,n]),!0}catch{return!1}}export function getGeminiGoogleOAuthTokens(){try{const e=_("gemini-google"),t=Q().read(),r=e?t?.providerProfileOauth?.[e]:null;if(r?.accessToken)return r;const n=Object.entries(t?.providerProfileOauth??{}).find(([e,t])=>e.startsWith("gemini-google/")&&"object"==typeof t&&null!==t&&"string"==typeof t.accessToken&&t.accessToken.trim())?.[1];return n?.accessToken?n:null}catch{return null}}export function saveGeminiGoogleOAuthTokens(e){const t=Q(),r=t.name;try{const n=t.read()||{},o=_("gemini-google")??g("gemini-google").id,s={accessToken:e.accessToken,refreshToken:e.refreshToken,expiresAt:e.expiresAt,scopes:e.scopes,subscriptionType:null,rateLimitTier:null,projectId:e.projectId};o&&(n.providerProfileOauth={...n.providerProfileOauth??{},[o]:s});const i=t.update(n);return a(i.success?"tengu_gemini_google_oauth_tokens_saved":"tengu_gemini_google_oauth_tokens_save_failed",{storageBackend:r}),i}catch(e){return J(e),a("tengu_gemini_google_oauth_tokens_save_exception",{storageBackend:r,error:W(e)}),{success:!1,warning:"Failed to save Gemini OAuth tokens"}}}export function getCopilotOAuthTokens(){try{const e=_("copilot"),t=Q().read(),r=e?t?.providerProfileOauth?.[e]:null;if(r?.githubToken||r?.accessToken)return r;const n=Object.entries(t?.providerProfileOauth??{}).find(([e,t])=>e.startsWith("copilot/")&&"object"==typeof t&&null!==t&&("string"==typeof t.githubToken||"string"==typeof t.accessToken))?.[1];return n?.githubToken||n?.accessToken?n:null}catch{return null}}export function saveCopilotOAuthTokens(e){const t=Q(),r=t.name;try{const n=t.read()||{},o=_("copilot")??g("copilot").id,s={accessToken:e.accessToken,refreshToken:e.refreshToken,expiresAt:e.expiresAt,scopes:e.scopes,subscriptionType:null,rateLimitTier:null,githubToken:e.githubToken};o&&(n.providerProfileOauth={...n.providerProfileOauth??{},[o]:s});const i=t.update(n);return a(i.success?"tengu_copilot_oauth_tokens_saved":"tengu_copilot_oauth_tokens_save_failed",{storageBackend:r}),i}catch(e){return J(e),a("tengu_copilot_oauth_tokens_save_exception",{storageBackend:r,error:W(e)}),{success:!1,warning:"Failed to save Copilot OAuth tokens"}}}export async function checkAndRefreshCopilotTokenIfNeeded(){const e=getCopilotOAuthTokens();if(!e)return null;const t=e.githubToken||e.accessToken;if(!t)return e;if(e.accessToken&&e.accessToken!==e.githubToken&&e.expiresAt&&e.expiresAt>Date.now()+6e4)return e;try{const r=await fetch("https://api.github.com/copilot_internal/v2/token",{method:"GET",headers:{Authorization:`token ${t}`,"User-Agent":"ContextCode/1.0",Accept:"application/json"}});if(!r.ok)return e;const n=await r.json(),o=n.expires_at?1e3*n.expires_at:Date.now()+15e5,s={...e,accessToken:n.token,githubToken:t,expiresAt:o};return saveCopilotOAuthTokens(s),s}catch{return e}}export function getCopilotAccessToken(){const e=process.env.GITHUB_COPILOT_TOKEN||process.env.COPILOT_OAUTH_TOKEN;if(e)return e;const t=getCopilotOAuthTokens();return t?.accessToken||t?.githubToken||null}function quoteShellArg(e){return`"${e.replace(/"/g,'\\"')}"`}export function getGeminiGoogleAuthCommand(){const e=process.env.GEMINI_OAUTH_CLIENT_SECRET_FILE||process.env.GOOGLE_OAUTH_CLIENT_SECRET_FILE,t=ge.join(",");return`gcloud auth application-default login${e?` --client-id-file=${quoteShellArg(e)}`:""} --scopes=${quoteShellArg(t)}`}export async function refreshGeminiGoogleAuth(){return refreshGcpAuth(getGeminiGoogleAuthCommand())}export function getGeminiApiAccessToken(){return process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||getStoredProviderApiKey("gemini-api",_("gemini-api"))||null}export async function getGeminiGoogleAuthHeaders(){const e=process.env.GEMINI_OAUTH_TOKEN||process.env.GOOGLE_OAUTH_ACCESS_TOKEN,t={"Content-Type":"application/json"};if(e)t.Authorization=`Bearer ${e}`;else{const e=await async function(){const e=getGeminiGoogleOAuthTokens();if(!e?.refreshToken)return e;if(e.expiresAt&&e.expiresAt>Date.now()+6e4)return e;const t=await fetch(A,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",refresh_token:e.refreshToken,client_id:u,client_secret:p})});if(!t.ok)return e;const r=await t.json(),n={...e,accessToken:r.access_token,expiresAt:r.expires_in?Date.now()+1e3*r.expires_in:e.expiresAt,scopes:r.scope?.split(/\s+/).filter(Boolean)??e.scopes};return saveGeminiGoogleOAuthTokens(n),n}();if(e?.accessToken){t.Authorization=`Bearer ${e.accessToken}`;const r=process.env.GEMINI_GOOGLE_PROJECT_ID?.trim();r&&(t["x-goog-user-project"]=r)}else{const{GoogleAuth:e}=await import("google-auth-library"),r=new e({scopes:ge}),n=await r.getClient(),o=await n.getRequestHeaders();if("function"==typeof o.forEach)o.forEach((e,r)=>{t[r]=e});else for(const[e,r]of Object.entries(o))Array.isArray(r)?t[e]=r.map(String).join(", "):null!=r&&(t[e]=String(r))}}const r=process.env.GEMINI_GOOGLE_PROJECT_ID?.trim()||void 0;return r&&(t["x-goog-user-project"]=r),t}export function getZAIAccessToken(){return process.env.ZAI_API_KEY||getStoredProviderApiKey("zai",_("zai"))||null}export function getMiniMaxAccessToken(){return process.env.MINIMAX_API_KEY||getStoredProviderApiKey("minimax",_("minimax"))||null}export function getNvidiaAccessToken(){return process.env.NVIDIA_API_KEY||getStoredProviderApiKey("nvidia",_("nvidia"))||null}export function getDeepSeekAccessToken(){return process.env.DEEPSEEK_API_KEY||getStoredProviderApiKey("deepseek",_("deepseek"))||null}export function getXaiAccessToken(){return process.env.XAI_API_KEY||getStoredProviderApiKey("xai",_("xai"))||null}export function getOllamaAccessToken(){return"ollama"}export function getOllamaCloudAccessToken(){return process.env.OLLAMA_API_KEY||getStoredProviderApiKey("ollama-cloud",_("ollama-cloud"))||null}export function getOpenAICompatibleAccessToken(e=h()){switch(e){case"openrouter":return getOpenRouterAccessToken();case"gemini-api":return getGeminiApiAccessToken();case"gemini-google":return process.env.GEMINI_OAUTH_TOKEN||process.env.GOOGLE_OAUTH_ACCESS_TOKEN||null;case"zai":return getZAIAccessToken();case"minimax":return getMiniMaxAccessToken();case"nvidia":return getNvidiaAccessToken();case"deepseek":return getDeepSeekAccessToken();case"xai":return getXaiAccessToken();case"copilot":return getCopilotAccessToken();case"gmi":case"novita":case"stepfun":case"huggingface":case"opencode-zen":case"arcee":case"alibaba":case"kimi":{const t=Ae[e];return(t?process.env[t]:void 0)||getStoredProviderApiKey(e,_(e))||null}case"ollama":return getOllamaAccessToken();case"ollama-cloud":return getOllamaCloudAccessToken();case"custom-openai":return process.env.CUSTOM_OPENAI_API_KEY||getStoredProviderApiKey("custom-openai",_("custom-openai"))||null;case"custom-anthropic":return process.env.CUSTOM_ANTHROPIC_API_KEY||getStoredProviderApiKey("custom-anthropic",_("custom-anthropic"))||null;default:return getOpenAIAccessToken()}}export async function getOpenAIOAuthTokensAsync(){if(B())return null;if(process.env.OPENAI_OAUTH_TOKEN)return getOpenAIOAuthTokens();try{const e=Q(),t=await e.readAsync(),r=_("openai"),n=r&&t?.providerProfileOauth?.[r]||(r&&!O("openai",r)?null:t?.openAiOauth);return n?.accessToken?n:null}catch(e){return J(e),null}}export function clearOAuthTokenCache(){getClaudeAIOAuthTokens.cache?.clear?.(),getOpenAIOAuthTokens.cache?.clear?.(),re()}let Te=0;async function invalidateOAuthCacheIfDiskChanged(){try{const e="sqlite"===Q().name?ie():se(),{mtimeMs:t}=await s(e);t!==Te&&(Te=t,clearOAuthTokenCache())}catch{getClaudeAIOAuthTokens.cache?.clear?.(),getOpenAIOAuthTokens.cache?.clear?.()}}const Ee=new Map;export function handleOAuth401Error(e){const t=Ee.get(e);if(t)return t;const r=async function(e){clearOAuthTokenCache();const t=await getClaudeAIOAuthTokensAsync();if(!t?.refreshToken)return!1;if(t.accessToken!==e)return a("tengu_oauth_401_recovered_from_keychain",{}),!0;return checkAndRefreshOAuthTokenIfNeeded(0,!0)}(e).finally(()=>{Ee.delete(e)});return Ee.set(e,r),r}export async function handleOpenAIOAuth401Error(e){clearOAuthTokenCache();const t=await getOpenAIOAuthTokensAsync();return!!t?.refreshToken&&(t.accessToken!==e?(a("tengu_openai_oauth_401_recovered_from_keychain",{}),!0):checkAndRefreshOpenAIOAuthTokenIfNeeded(0,!0))}export async function getClaudeAIOAuthTokensAsync(){if(B())return null;if(isManagedOAuthContext()&&(process.env.CONTEXT_CODE_OAUTH_TOKEN||process.env.CLAUDE_CODE_OAUTH_TOKEN||w()))return getClaudeAIOAuthTokens();try{const e=Q(),t=await e.readAsync(),r=_("claude"),n=r&&t?.providerProfileOauth?.[r]||(r&&!O("claude",r)?null:t?.claudeAiOauth);return n?.accessToken?n:null}catch(e){return J(e),null}}let me=null,ke=null;export function checkAndRefreshOAuthTokenIfNeeded(e=0,t=!1){if(0===e&&!t){if(me)return me;const r=checkAndRefreshOAuthTokenIfNeededImpl(e,t);return me=r.finally(()=>{me=null}),me}return checkAndRefreshOAuthTokenIfNeededImpl(e,t)}export function checkAndRefreshOpenAIOAuthTokenIfNeeded(e=0,t=!1){if(0===e&&!t){if(ke)return ke;const r=checkAndRefreshOpenAIOAuthTokenIfNeededImpl(e,t);return ke=r.finally(()=>{ke=null}),ke}return checkAndRefreshOpenAIOAuthTokenIfNeededImpl(e,t)}async function checkAndRefreshOAuthTokenIfNeededImpl(e,t){await invalidateOAuthCacheIfDiskChanged();const r=getClaudeAIOAuthTokens();if(!(t||r?.refreshToken&&v(r.expiresAt)))return!1;if(!r?.refreshToken)return!1;if(!P(r.scopes))return!1;getClaudeAIOAuthTokens.cache?.clear?.(),re();const n=await getClaudeAIOAuthTokensAsync();if(!n?.refreshToken||!v(n.expiresAt))return!1;const s=$();let i;await o(s,{recursive:!0});try{a("tengu_oauth_token_refresh_lock_acquiring",{}),i=await V.lock(s),a("tengu_oauth_token_refresh_lock_acquired",{})}catch(r){return"ELOCKED"===r.code?e<5?(a("tengu_oauth_token_refresh_lock_retry",{retryCount:e+1}),await ue(1e3+1e3*Math.random()),checkAndRefreshOAuthTokenIfNeededImpl(e+1,t)):(a("tengu_oauth_token_refresh_lock_retry_limit_reached",{maxRetries:5}),!1):(J(r),a("tengu_oauth_token_refresh_lock_error",{error:W(r)}),!1)}try{getClaudeAIOAuthTokens.cache?.clear?.(),re();const e=await getClaudeAIOAuthTokensAsync();if(!e?.refreshToken||!v(e.expiresAt))return a("tengu_oauth_token_refresh_race_resolved",{}),!1;a("tengu_oauth_token_refresh_starting",{});return saveOAuthTokensIfNeeded(await K(e.refreshToken,{scopes:P(e.scopes)?void 0:e.scopes})),getClaudeAIOAuthTokens.cache?.clear?.(),re(),!0}catch(e){J(e),getClaudeAIOAuthTokens.cache?.clear?.(),re();const t=await getClaudeAIOAuthTokensAsync();return!(!t||v(t.expiresAt))&&(a("tengu_oauth_token_refresh_race_recovered",{}),!0)}finally{a("tengu_oauth_token_refresh_lock_releasing",{}),await i(),a("tengu_oauth_token_refresh_lock_released",{})}}async function checkAndRefreshOpenAIOAuthTokenIfNeededImpl(e,t){await invalidateOAuthCacheIfDiskChanged();const r=getOpenAIOAuthTokens();if(!(t||r?.refreshToken&&v(r.expiresAt)))return!1;if(!r?.refreshToken)return!1;getOpenAIOAuthTokens.cache?.clear?.(),re();const n=await getOpenAIOAuthTokensAsync();if(!n?.refreshToken||!v(n.expiresAt))return!1;const s=$();let i;await o(s,{recursive:!0});try{a("tengu_openai_oauth_token_refresh_lock_acquiring",{}),i=await V.lock(s),a("tengu_openai_oauth_token_refresh_lock_acquired",{})}catch(r){return"ELOCKED"===r.code?e<5?(a("tengu_openai_oauth_token_refresh_lock_retry",{retryCount:e+1}),await ue(1e3+1e3*Math.random()),checkAndRefreshOpenAIOAuthTokenIfNeededImpl(e+1,t)):(a("tengu_openai_oauth_token_refresh_lock_retry_limit_reached",{maxRetries:5}),!1):(J(r),!1)}try{getOpenAIOAuthTokens.cache?.clear?.(),re();const e=await getOpenAIOAuthTokensAsync();if(!e?.refreshToken||!v(e.expiresAt))return a("tengu_openai_oauth_token_refresh_race_resolved",{}),!1;a("tengu_openai_oauth_token_refresh_starting",{});return saveOpenAIOAuthTokens(await I(e.refreshToken,{scopes:e.scopes})),getOpenAIOAuthTokens.cache?.clear?.(),re(),!0}catch(e){J(e),getOpenAIOAuthTokens.cache?.clear?.(),re();const t=await getOpenAIOAuthTokensAsync();return!(!t||v(t.expiresAt))&&(a("tengu_openai_oauth_token_refresh_race_recovered",{}),!0)}finally{a("tengu_openai_oauth_token_refresh_lock_releasing",{}),await i(),a("tengu_openai_oauth_token_refresh_lock_released",{})}}export function isClaudeAISubscriber(){return!!isAnthropicAuthEnabled()&&P(getClaudeAIOAuthTokens()?.scopes)}export function hasProfileScope(){return getClaudeAIOAuthTokens()?.scopes?.includes(c)??!1}export function is1PApiCustomer(){return!(X(process.env.CONTEXT_CODE_USE_BEDROCK)||X(process.env.CLAUDE_CODE_USE_BEDROCK)||X(process.env.CONTEXT_CODE_USE_VERTEX)||X(process.env.CLAUDE_CODE_USE_VERTEX)||X(process.env.CONTEXT_CODE_USE_FOUNDRY)||X(process.env.CLAUDE_CODE_USE_FOUNDRY)||f(h()))&&!isClaudeAISubscriber()}export function getOauthAccountInfo(){return isAnthropicAuthEnabled()?G().oauthAccount:void 0}export function isOverageProvisioningAllowed(){const e=getOauthAccountInfo(),t=e?.billingType;return!(!isClaudeAISubscriber()||!t)&&("stripe_subscription"===t||"stripe_subscription_contracted"===t||"apple_subscription"===t||"google_play_subscription"===t)}export function hasOpusAccess(){const e=getSubscriptionType();return"max"===e||"enterprise"===e||"team"===e||"pro"===e||null===e}export function getSubscriptionType(){if(C())return y();if(!isAnthropicAuthEnabled())return null;const e=getClaudeAIOAuthTokens();return e?e.subscriptionType??null:null}export function isMaxSubscriber(){return"max"===getSubscriptionType()}export function isTeamSubscriber(){return"team"===getSubscriptionType()}export function isTeamPremiumSubscriber(){return"team"===getSubscriptionType()&&"default_claude_max_5x"===getRateLimitTier()}export function isEnterpriseSubscriber(){return"enterprise"===getSubscriptionType()}export function isProSubscriber(){return"pro"===getSubscriptionType()}export function getRateLimitTier(){if(!isAnthropicAuthEnabled())return null;const e=getClaudeAIOAuthTokens();return e?e.rateLimitTier??null:null}export function getSubscriptionName(){switch(getSubscriptionType()){case"enterprise":return"Context Empresarial";case"team":return"Context Equipo";case"max":return"Context Max";case"pro":return"Context Pro";default:return"Context API"}}export function isUsing3PServices(){return!!(X(process.env.CONTEXT_CODE_USE_BEDROCK)||X(process.env.CLAUDE_CODE_USE_BEDROCK)||X(process.env.CONTEXT_CODE_USE_VERTEX)||X(process.env.CLAUDE_CODE_USE_VERTEX)||X(process.env.CONTEXT_CODE_USE_FOUNDRY)||X(process.env.CLAUDE_CODE_USE_FOUNDRY)||f(h()))}function getConfiguredOtelHeadersHelper(){return(ce()||{}).otelHeadersHelper}export function isOtelHeadersHelperFromProjectOrLocalSettings(){const e=getConfiguredOtelHeadersHelper();if(!e)return!1;const t=ae("projectSettings"),r=ae("localSettings");return t?.otelHeadersHelper===e||r?.otelHeadersHelper===e}let ye=null,Ce=0;const ve=174e4;export function getOtelHeadersFromHelper(){const e=getConfiguredOtelHeadersHelper();if(!e)return{};const t=parseInt(process.env.CONTEXT_CODE_OTEL_HEADERS_HELPER_DEBOUNCE_MS||process.env.CLAUDE_CODE_OTEL_HEADERS_HELPER_DEBOUNCE_MS||ve.toString());if(ye&&Date.now()-Ce<t)return ye;if(isOtelHeadersHelperFromProjectOrLocalSettings()){if(!j())return{}}try{const t=q(e,{timeout:3e4})?.toString().trim();if(!t)throw new Error("otelHeadersHelper did not return a valid value");const r=pe(t);if("object"!=typeof r||null===r||Array.isArray(r))throw new Error("otelHeadersHelper must return a JSON object with string key-value pairs");for(const[e,t]of Object.entries(r))if("string"!=typeof t)throw new Error(`otelHeadersHelper returned non-string value for key "${e}": ${typeof t}`);return ye=r,Ce=Date.now(),ye}catch(e){throw J(new Error(`Error getting OpenTelemetry headers from otelHeadersHelper (in settings): ${W(e)}`)),e}}export function isConsumerSubscriber(){const e=getSubscriptionType();return isClaudeAISubscriber()&&null!==e&&("max"===(t=e)||"pro"===t);var t}export function getAccountInformation(){if("firstParty"!==h())return;const{source:e}=getAuthTokenSource(),t={};"CLAUDE_CODE_OAUTH_TOKEN"===e||"CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR"===e?t.tokenSource=e:isClaudeAISubscriber()?t.subscription=getSubscriptionName():t.tokenSource=e;const{key:r,source:n}=getAnthropicApiKeyWithSource();if(r&&(t.apiKeySource=n),"claude.ai"===e||"/login managed key"===n){const e=getOauthAccountInfo()?.organizationName;e&&(t.organization=e)}const o=getOauthAccountInfo()?.emailAddress;return"claude.ai"!==e&&"/login managed key"!==n||!o||(t.email=o),t}export async function validateForceLoginOrg(){if(process.env.ANTHROPIC_UNIX_SOCKET)return{valid:!0};if(!isAnthropicAuthEnabled())return{valid:!0};const e=ae("policySettings")?.forceLoginOrgUUID;if(!e)return{valid:!0};await checkAndRefreshOAuthTokenIfNeeded();const t=getClaudeAIOAuthTokens();if(!t)return{valid:!0};const{source:r}=getAuthTokenSource(),n="CLAUDE_CODE_OAUTH_TOKEN"===r||"CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR"===r,o=await S(t.accessToken);if(!o)return{valid:!1,message:`Unable to verify organization for the current authentication token.\nThis machine requires organization ${e} but the profile could not be fetched.\nThis may be a network error, or the token may lack the user:profile scope required for\nverification (tokens from 'context setup-token' do not include this scope).\nTry again, or obtain a full-scope token via 'context auth login'.`};const s=o.organization.uuid;if(s===e)return{valid:!0};if(n){return{valid:!1,message:`The ${"CLAUDE_CODE_OAUTH_TOKEN"===r?"CLAUDE_CODE_OAUTH_TOKEN":"CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR"} environment variable provides a token for a\ndifferent organization than required by this machine's managed settings.\n\nRequired organization: ${e}\nToken organization: ${s}\n\nRemove the environment variable or obtain a token for the correct organization.`}}return{valid:!1,message:`Your authentication token belongs to organization ${s},\nbut this machine requires organization ${e}.\n\nPlease log in with the correct organization: context auth login`}}class GcpCredentialsTimeoutError extends Error{}
@@ -1 +1 @@
1
- import{execa as e}from"execa";import{getCwd as t}from"./cwd.js";import{logError as r}from"./log.js";export{execSyncWithDefaults_DEPRECATED}from"./execFileNoThrowPortable.js";export function execFileNoThrow(e,r,o={timeout:6e5,preserveOutputOnError:!0,useCwd:!0}){return execFileNoThrowWithCwd(e,r,{abortSignal:o.abortSignal,timeout:o.timeout,preserveOutputOnError:o.preserveOutputOnError,cwd:o.useCwd?t():void 0,env:o.env,stdin:o.stdin,input:o.input})}function getErrorMessage(e,t){return e.shortMessage?e.shortMessage:"string"==typeof e.signal?e.signal:String(t)}export function execFileNoThrowWithCwd(t,o,{abortSignal:s,timeout:i=6e5,preserveOutputOnError:n=!0,cwd:u,env:d,maxBuffer:c,shell:a,stdin:p,input:l}={timeout:6e5,preserveOutputOnError:!0,maxBuffer:1e6}){return new Promise(f=>{e(t,o,{maxBuffer:c,signal:s,timeout:i,cwd:u,env:d,shell:a,stdin:p,input:l,reject:!1}).then(e=>{if(e.failed)if(n){const t=e.exitCode??1;f({stdout:e.stdout||"",stderr:e.stderr||"",code:t,error:getErrorMessage(e,t)})}else f({stdout:"",stderr:"",code:e.exitCode??1});else f({stdout:e.stdout,stderr:e.stderr,code:0})}).catch(e=>{r(e),f({stdout:"",stderr:"",code:1})})})}
1
+ import{execa as e}from"execa";import{getCwd as t}from"./cwd.js";import{logError as r}from"./log.js";export{execSyncWithDefaults_DEPRECATED}from"./execFileNoThrowPortable.js";export function execFileNoThrow(e,r,o={timeout:6e5,preserveOutputOnError:!0,useCwd:!0}){return execFileNoThrowWithCwd(e,r,{abortSignal:o.abortSignal,timeout:o.timeout,preserveOutputOnError:o.preserveOutputOnError,cwd:o.useCwd?t():void 0,env:o.env,stdin:o.stdin,input:o.input})}function getErrorMessage(e,t){return e.shortMessage?e.shortMessage:"string"==typeof e.signal?e.signal:String(t)}export function execFileNoThrowWithCwd(t,o,{abortSignal:s,timeout:i=6e5,preserveOutputOnError:n=!0,cwd:u,env:d,maxBuffer:c,shell:a,stdin:l,input:p}={timeout:6e5,preserveOutputOnError:!0,maxBuffer:1e6}){return new Promise(f=>{e(t,o,{maxBuffer:c,cancelSignal:s,timeout:i,cwd:u,env:d,shell:a,stdin:l,input:p,reject:!1}).then(e=>{if(e.failed)if(n){const t=e.exitCode??1;f({stdout:e.stdout||"",stderr:e.stderr||"",code:t,error:getErrorMessage(e,t)})}else f({stdout:"",stderr:"",code:e.exitCode??1});else f({stdout:e.stdout,stderr:e.stderr,code:0})}).catch(e=>{r(e),f({stdout:"",stderr:"",code:1})})})}
@@ -1 +1 @@
1
- import{createRequire as e}from"module";import{randomUUID as t}from"node:crypto";import{join as n}from"path";import{getGlobalConfig as i,saveGlobalConfig as r}from"../config.js";import{getClaudeConfigHomeDir as a}from"../envUtils.js";import{getFsImplementation as o}from"../fsOperations.js";import{getSecureStorage as E}from"../secureStorage/index.js";function hasStoredCredentialForProvider(e,t){if(!e)return!1;if("openai"===t&&e.openAiOauth?.accessToken)return!0;if("claude"===t&&e.claudeAiOauth?.accessToken)return!0;if(Object.keys(e.providerProfileOauth??{}).some(e=>e.startsWith(`${t}/`)))return!0;if(e.providerApiKeys?.[t])return!0;return Object.keys(e.providerProfileApiKeys??{}).some(e=>e.startsWith(`${t}/`))}const d=e(import.meta.url);let _=null,s=!1,T=!1;const l="active_provider",N="active_profile_id",p=["claude","openai","openrouter","ollama","ollama-cloud","lmstudio","gemini-api","gemini-google","zai","minimax","deepseek","copilot"],c={claude:"main",openai:"main",openrouter:"main",ollama:"local","ollama-cloud":"main",lmstudio:"local","gemini-api":"main","gemini-google":"main",zai:"main",minimax:"main",nvidia:"main",deepseek:"main",copilot:"main"},L={claude:"claude",openai:"openai",openrouter:"openrouter",ollama:"ollama-local","ollama-cloud":"ollama-cloud",lmstudio:"lmstudio-local","gemini-api":"gemini-api","gemini-google":"gemini-google",zai:"z-ai",minimax:"minimax",nvidia:"nvidia",deepseek:"deepseek",copilot:"copilot"},u={openrouter:"https://openrouter.ai/api/v1",ollama:"http://localhost:11434/v1","ollama-cloud":"http://localhost:11434/v1",lmstudio:"http://localhost:1234/v1","gemini-api":"https://generativelanguage.googleapis.com/v1beta/openai","gemini-google":"https://generativelanguage.googleapis.com/v1beta/openai",zai:"https://api.z.ai/api/coding/paas/v4",minimax:"https://api.minimax.io/anthropic",deepseek:"https://api.deepseek.com/v1"},m={claude:"Claude",openai:"OpenAI",openrouter:"OpenRouter",ollama:"Ollama","ollama-cloud":"Ollama Cloud",lmstudio:"LM Studio","gemini-api":"Gemini API","gemini-google":"Gemini Google",zai:"Z.AI",minimax:"MiniMax",nvidia:"NVIDIA NIM",deepseek:"DeepSeek"},O=["openrouter","ollama","ollama-cloud","gemini-api","gemini-google","zai","minimax","deepseek"];function sanitizeProfileSegment(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"default"}function buildProfileId(e,t){return`${e}/${sanitizeProfileSegment(t)}`}function buildDefaultAgentName(e,t){const n=L[e],i=sanitizeProfileSegment(t);return i===sanitizeProfileSegment(c[e])?n:`${n}-${i}`}function tableExists(e,t){const n=e.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?").get(t);return Boolean(n)}function columnExists(e,t,n){return e.prepare(`PRAGMA table_info(${t})`).all().some(e=>e.name===n)}function migrateTeamUnitsSchema(e){e.exec("PRAGMA foreign_keys = OFF;");try{tableExists(e,"team_domains")&&e.exec("\n INSERT OR IGNORE INTO team_units (\n id, team_id, unit_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at\n )\n SELECT id, team_id, domain_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at\n FROM team_domains;\n "),tableExists(e,"team_domain_members")&&e.exec("\n INSERT OR IGNORE INTO team_unit_members (\n id, team_unit_id, agent_id, duty, priority, created_at, updated_at\n )\n SELECT id, team_domain_id, agent_id, duty, priority, created_at, updated_at\n FROM team_domain_members;\n "),tableExists(e,"orchestration_tasks")&&!columnExists(e,"orchestration_tasks","team_unit_id")&&e.exec("ALTER TABLE orchestration_tasks ADD COLUMN team_unit_id TEXT NULL;"),tableExists(e,"orchestration_tasks")&&columnExists(e,"orchestration_tasks","team_domain_id")&&columnExists(e,"orchestration_tasks","team_unit_id")&&e.exec("\n UPDATE orchestration_tasks\n SET team_unit_id = team_domain_id\n WHERE team_unit_id IS NULL AND team_domain_id IS NOT NULL;\n "),function(e){tableExists(e,"orchestration_tasks")&&columnExists(e,"orchestration_tasks","team_domain_id")&&e.exec("\n CREATE TABLE IF NOT EXISTS orchestration_tasks_v8 (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n parent_task_id TEXT NULL,\n scope_type TEXT NOT NULL,\n team_unit_id TEXT NULL,\n assigned_agent_id TEXT NULL,\n title TEXT NOT NULL,\n instructions TEXT NOT NULL,\n status TEXT NOT NULL,\n result_summary TEXT NULL,\n created_at TEXT NOT NULL,\n finished_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (parent_task_id) REFERENCES orchestration_tasks_v8(id) ON DELETE SET NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE SET NULL,\n FOREIGN KEY (assigned_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n INSERT OR REPLACE INTO orchestration_tasks_v8 (\n id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at\n )\n SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at\n FROM orchestration_tasks;\n\n DROP TABLE orchestration_tasks;\n ALTER TABLE orchestration_tasks_v8 RENAME TO orchestration_tasks;\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_run_id\n ON orchestration_tasks(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_team_unit_id\n ON orchestration_tasks(team_unit_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_assigned_agent_id\n ON orchestration_tasks(assigned_agent_id);\n ")}(e),tableExists(e,"orchestration_domain_reports")&&e.exec("\n INSERT OR IGNORE INTO orchestration_team_reports (\n id, run_id, team_unit_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at\n )\n SELECT id, run_id, team_domain_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at\n FROM orchestration_domain_reports;\n "),tableExists(e,"provider_agent_capability_rankings")&&!columnExists(e,"provider_agent_capability_rankings","team_unit_id")&&e.exec("ALTER TABLE provider_agent_capability_rankings ADD COLUMN team_unit_id TEXT NULL;"),tableExists(e,"provider_agent_capability_rankings")&&columnExists(e,"provider_agent_capability_rankings","team_domain_id")&&columnExists(e,"provider_agent_capability_rankings","team_unit_id")&&e.exec("\n UPDATE provider_agent_capability_rankings\n SET team_unit_id = team_domain_id\n WHERE team_unit_id IS NULL AND team_domain_id IS NOT NULL;\n "),function(e){tableExists(e,"provider_agent_capability_rankings")&&columnExists(e,"provider_agent_capability_rankings","team_domain_id")&&e.exec("\n CREATE TABLE IF NOT EXISTS provider_agent_capability_rankings_v8 (\n id TEXT PRIMARY KEY,\n team_unit_id TEXT NULL,\n capability TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n score REAL NOT NULL DEFAULT 0,\n reason TEXT NULL,\n source TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (team_unit_id, capability, agent_id)\n );\n\n INSERT OR REPLACE INTO provider_agent_capability_rankings_v8 (\n id, team_unit_id, capability, agent_id, score, reason, source, created_at, updated_at\n )\n SELECT id, team_unit_id, capability, agent_id, score, reason, source, created_at, updated_at\n FROM provider_agent_capability_rankings;\n\n DROP TABLE provider_agent_capability_rankings;\n ALTER TABLE provider_agent_capability_rankings_v8 RENAME TO provider_agent_capability_rankings;\n\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_team_unit\n ON provider_agent_capability_rankings(team_unit_id);\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_capability\n ON provider_agent_capability_rankings(capability);\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_agent\n ON provider_agent_capability_rankings(agent_id);\n ")}(e),e.exec("\n DROP TABLE IF EXISTS orchestration_domain_reports;\n DROP TABLE IF EXISTS team_domain_members;\n DROP TABLE IF EXISTS team_domains;\n ")}finally{e.exec("PRAGMA foreign_keys = ON;")}tableExists(e,"orchestration_tasks")&&columnExists(e,"orchestration_tasks","team_unit_id")&&e.exec("\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_team_unit_id\n ON orchestration_tasks(team_unit_id);\n "),tableExists(e,"provider_agent_capability_rankings")&&columnExists(e,"provider_agent_capability_rankings","team_unit_id")&&e.exec("\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_team_unit\n ON provider_agent_capability_rankings(team_unit_id);\n ")}function getDatabasePath(){return n(a(),"provider-state.sqlite3")}function rowToProfile(e){if(!e)return null;const t=e;return{id:t.id,provider:t.provider,name:t.name,agentName:t.agent_name,baseUrl:t.base_url??void 0,lastModel:t.last_model,createdAt:t.created_at,updatedAt:t.updated_at}}function seedLegacyProfiles(){const e=i(),t=e.providerProfiles,n={...t&&"object"==typeof t&&t.profiles?t.profiles:{}},r={...t&&"object"==typeof t&&t.lastProfileIdByProvider?t.lastProfileIdByProvider:{}},a=(()=>{try{return E().read()}catch{return null}})();for(const t of p){const i=Object.values(n).some(e=>e.provider===t),o=e.providerBaseUrls?.[t],E=e.lastModelByProvider?.[t]??null;if(!(i||e.activeProvider===t||Boolean(o)||null!==E||hasStoredCredentialForProvider(a,t))||i)continue;const d=c[t],_=buildProfileId(t,d),s=(new Date).toISOString();n[_]={id:_,provider:t,name:d,agentName:buildDefaultAgentName(t,d),baseUrl:o??u[t],lastModel:E,createdAt:s,updatedAt:s},r[t]=_}return{version:1,activeProfileId:(t&&"object"==typeof t?t.activeProfileId:void 0)??(e.activeProvider&&p.includes(e.activeProvider)?r[e.activeProvider]:void 0),lastProfileIdByProvider:r,profiles:n}}function migrateFromLegacyConfig(e){const t=i(),n=seedLegacyProfiles(),r=e.prepare("\n INSERT OR REPLACE INTO provider_profiles (\n id, provider, name, agent_name, base_url, last_model, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n "),a=e.prepare("\n INSERT INTO provider_last_profile (provider, profile_id)\n VALUES (?, ?)\n ON CONFLICT(provider) DO UPDATE SET profile_id = excluded.profile_id\n "),o=e.prepare("\n INSERT INTO provider_runtime_state (key, value)\n VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = excluded.value\n "),E=e.prepare("\n INSERT INTO provider_last_model (provider, last_model, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n last_model = excluded.last_model,\n updated_at = excluded.updated_at\n "),d=e.prepare("\n INSERT INTO provider_base_url (provider, base_url, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n base_url = excluded.base_url,\n updated_at = excluded.updated_at\n ");for(const e of Object.values(n.profiles??{}))r.run(e.id,e.provider,e.name,e.agentName,e.baseUrl??null,e.lastModel??null,e.createdAt,e.updatedAt);for(const[e,t]of Object.entries(n.lastProfileIdByProvider??{}))t&&a.run(e,t);n.activeProfileId&&o.run(N,n.activeProfileId);const _=t.activeProvider??(n.activeProfileId?n.profiles?.[n.activeProfileId]?.provider:void 0);_&&o.run(l,_);const s={claude:t.lastClaudeModel??t.lastModelByProvider?.claude??null,openai:t.lastOpenAIModel??t.lastModelByProvider?.openai??null,openrouter:t.lastOpenRouterModel??t.lastModelByProvider?.openrouter??null,ollama:t.lastModelByProvider?.ollama??null,"ollama-cloud":t.lastModelByProvider?.["ollama-cloud"]??null,"gemini-api":t.lastModelByProvider?.["gemini-api"]??null,"gemini-google":t.lastModelByProvider?.["gemini-google"]??null,zai:t.lastModelByProvider?.zai??null,minimax:t.lastModelByProvider?.minimax??null,deepseek:t.lastModelByProvider?.deepseek??null};for(const e of p)E.run(e,s[e]??null,(new Date).toISOString());for(const e of O){const n=t.providerBaseUrls?.[e];"string"==typeof n&&n.trim()&&d.run(e,n.trim(),(new Date).toISOString())}}export function purgeLegacyProviderStateInConfig(){hasLegacyProviderStateInConfig()&&r(e=>({...e,activeProvider:void 0,lastModelByProvider:{},providerBaseUrls:void 0,lastOpenAIModel:void 0,lastClaudeModel:void 0,lastOpenRouterModel:void 0,providerProfiles:void 0}))}export function finalizeProviderProfilesMigration(){ensureInitialized(),purgeLegacyProviderStateInConfig()}function ensureInitialized(){const e=function(){if(T)throw new Error("SQLite no disponible en este runtime.");if(_)return _;let e;o().mkdirSync(a(),{mode:448});try{e=d("node:sqlite")}catch(e){throw T=!0,e}return _=new e.DatabaseSync(getDatabasePath()),_}();if(s)return e;e.exec("\n PRAGMA journal_mode = WAL;\n PRAGMA foreign_keys = ON;\n PRAGMA synchronous = NORMAL;\n\n CREATE TABLE IF NOT EXISTS provider_profiles (\n id TEXT PRIMARY KEY,\n provider TEXT NOT NULL,\n name TEXT NOT NULL,\n agent_name TEXT NOT NULL,\n base_url TEXT NULL,\n last_model TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_last_profile (\n provider TEXT PRIMARY KEY,\n profile_id TEXT NOT NULL,\n FOREIGN KEY (profile_id) REFERENCES provider_profiles(id) ON DELETE CASCADE\n );\n\n CREATE TABLE IF NOT EXISTS provider_runtime_state (\n key TEXT PRIMARY KEY,\n value TEXT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_last_model (\n provider TEXT PRIMARY KEY,\n last_model TEXT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_base_url (\n provider TEXT PRIMARY KEY,\n base_url TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_workspaces (\n id TEXT PRIMARY KEY,\n provider TEXT NOT NULL UNIQUE,\n display_name TEXT NOT NULL,\n domain_focus TEXT NULL,\n is_enabled INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_agents (\n id TEXT PRIMARY KEY,\n workspace_id TEXT NOT NULL,\n profile_id TEXT NOT NULL,\n name TEXT NOT NULL,\n role_kind TEXT NULL,\n system_prompt TEXT NULL,\n model_override TEXT NULL,\n tool_policy TEXT NULL,\n autonomy_level TEXT NULL,\n is_orchestrator INTEGER NOT NULL DEFAULT 0,\n is_enabled INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (workspace_id) REFERENCES provider_workspaces(id) ON DELETE CASCADE,\n FOREIGN KEY (profile_id) REFERENCES provider_profiles(id) ON DELETE CASCADE,\n UNIQUE (workspace_id, name)\n );\n\n CREATE INDEX IF NOT EXISTS idx_provider_agents_workspace_id\n ON provider_agents(workspace_id);\n CREATE INDEX IF NOT EXISTS idx_provider_agents_profile_id\n ON provider_agents(profile_id);\n\n CREATE TABLE IF NOT EXISTS provider_agent_capabilities (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL,\n capability TEXT NOT NULL,\n weight REAL NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (agent_id, capability)\n );\n\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capabilities_agent_id\n ON provider_agent_capabilities(agent_id);\n\n CREATE TABLE IF NOT EXISTS teams (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n description TEXT NULL,\n global_orchestrator_agent_id TEXT NULL,\n is_enabled INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (global_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE TABLE IF NOT EXISTS team_units (\n id TEXT PRIMARY KEY,\n team_id TEXT NOT NULL,\n unit_name TEXT NOT NULL,\n workspace_id TEXT NULL,\n local_orchestrator_agent_id TEXT NULL,\n lead_agent_id TEXT NULL,\n selection_mode TEXT NOT NULL DEFAULT 'manual',\n required INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE,\n FOREIGN KEY (workspace_id) REFERENCES provider_workspaces(id) ON DELETE SET NULL,\n FOREIGN KEY (local_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n FOREIGN KEY (lead_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n UNIQUE (team_id, unit_name)\n );\n\n CREATE INDEX IF NOT EXISTS idx_team_units_team_id\n ON team_units(team_id);\n CREATE INDEX IF NOT EXISTS idx_team_units_workspace_id\n ON team_units(workspace_id);\n CREATE INDEX IF NOT EXISTS idx_team_units_local_orchestrator_agent_id\n ON team_units(local_orchestrator_agent_id);\n CREATE INDEX IF NOT EXISTS idx_team_units_lead_agent_id\n ON team_units(lead_agent_id);\n\n CREATE TABLE IF NOT EXISTS team_unit_members (\n id TEXT PRIMARY KEY,\n team_unit_id TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n duty TEXT NULL,\n priority INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (team_unit_id, agent_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_team_unit_members_team_unit_id\n ON team_unit_members(team_unit_id);\n CREATE INDEX IF NOT EXISTS idx_team_unit_members_agent_id\n ON team_unit_members(agent_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_runs (\n id TEXT PRIMARY KEY,\n team_id TEXT NOT NULL,\n goal TEXT NOT NULL,\n global_orchestrator_agent_id TEXT NULL,\n status TEXT NOT NULL,\n created_at TEXT NOT NULL,\n started_at TEXT NULL,\n finished_at TEXT NULL,\n FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE,\n FOREIGN KEY (global_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_runs_team_id\n ON orchestration_runs(team_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_runs_status\n ON orchestration_runs(status);\n\n CREATE TABLE IF NOT EXISTS orchestration_tasks (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n parent_task_id TEXT NULL,\n scope_type TEXT NOT NULL,\n team_unit_id TEXT NULL,\n assigned_agent_id TEXT NULL,\n title TEXT NOT NULL,\n instructions TEXT NOT NULL,\n status TEXT NOT NULL,\n result_summary TEXT NULL,\n created_at TEXT NOT NULL,\n finished_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (parent_task_id) REFERENCES orchestration_tasks(id) ON DELETE SET NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE SET NULL,\n FOREIGN KEY (assigned_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_run_id\n ON orchestration_tasks(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_assigned_agent_id\n ON orchestration_tasks(assigned_agent_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_messages (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n task_id TEXT NULL,\n from_agent_id TEXT NULL,\n to_agent_id TEXT NULL,\n message_type TEXT NOT NULL,\n content TEXT NOT NULL,\n created_at TEXT NOT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (task_id) REFERENCES orchestration_tasks(id) ON DELETE SET NULL,\n FOREIGN KEY (from_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n FOREIGN KEY (to_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_messages_run_id\n ON orchestration_messages(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_messages_task_id\n ON orchestration_messages(task_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_task_results (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n task_id TEXT NOT NULL,\n agent_id TEXT NULL,\n result_type TEXT NOT NULL,\n status TEXT NOT NULL,\n summary TEXT NULL,\n content TEXT NULL,\n metadata_json TEXT NULL,\n created_at TEXT NOT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (task_id) REFERENCES orchestration_tasks(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_task_results_run_id\n ON orchestration_task_results(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_task_results_task_id\n ON orchestration_task_results(task_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_task_results_agent_id\n ON orchestration_task_results(agent_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_team_reports (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n team_unit_id TEXT NOT NULL,\n local_orchestrator_agent_id TEXT NULL,\n status TEXT NOT NULL,\n summary TEXT NOT NULL,\n blockers TEXT NULL,\n output TEXT NULL,\n metrics_json TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n submitted_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (local_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n UNIQUE (run_id, team_unit_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_team_reports_run_id\n ON orchestration_team_reports(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_team_reports_team_unit_id\n ON orchestration_team_reports(team_unit_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_run_reports (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL UNIQUE,\n status TEXT NOT NULL,\n summary TEXT NOT NULL,\n output TEXT NULL,\n risks TEXT NULL,\n next_steps TEXT NULL,\n metrics_json TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n submitted_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_run_reports_run_id\n ON orchestration_run_reports(run_id);\n\n CREATE TABLE IF NOT EXISTS provider_agent_capability_rankings (\n id TEXT PRIMARY KEY,\n team_unit_id TEXT NULL,\n capability TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n score REAL NOT NULL DEFAULT 0,\n reason TEXT NULL,\n source TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (team_unit_id, capability, agent_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_capability\n ON provider_agent_capability_rankings(capability);\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_agent\n ON provider_agent_capability_rankings(agent_id);\n\n CREATE TABLE IF NOT EXISTS secure_storage (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS projects (\n path TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n created_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS permission_rules (\n id TEXT PRIMARY KEY,\n scope TEXT NOT NULL,\n scope_path TEXT NULL,\n tool_name TEXT NOT NULL,\n behavior TEXT NOT NULL,\n created_at TEXT NOT NULL,\n expires_at TEXT NULL,\n UNIQUE (scope, scope_path, tool_name)\n );\n\n CREATE INDEX IF NOT EXISTS idx_permission_rules_scope\n ON permission_rules(scope, scope_path);\n CREATE INDEX IF NOT EXISTS idx_permission_rules_tool_name\n ON permission_rules(tool_name);\n\n CREATE TABLE IF NOT EXISTS permission_mode_config (\n id TEXT PRIMARY KEY,\n scope TEXT NOT NULL,\n scope_path TEXT NULL,\n mode TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE (scope, scope_path)\n );\n\n CREATE TABLE IF NOT EXISTS trusted_directories (\n path TEXT PRIMARY KEY,\n trust_level TEXT NOT NULL DEFAULT 'full',\n created_at TEXT NOT NULL\n );\n "),migrateTeamUnitsSchema(e);const n=e.prepare("PRAGMA user_version").get();(n?.user_version??0)<8&&e.exec("PRAGMA user_version = 8"),function(e){const n=(new Date).toISOString(),i=e.prepare("\n INSERT OR IGNORE INTO provider_workspaces (\n id, provider, display_name, domain_focus, is_enabled, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n ");for(const e of p)i.run(t(),e,m[e],null,1,n,n)}(e);const i=e.prepare("SELECT COUNT(*) AS count FROM provider_profiles").get();if(0===(i?.count??0))migrateFromLegacyConfig(e);else{const t=e.prepare("SELECT COUNT(*) AS count FROM provider_last_model").get();0===(t?.count??0)&&migrateFromLegacyConfig(e);const n=e.prepare("SELECT COUNT(*) AS count FROM provider_base_url").get();0===(n?.count??0)&&migrateFromLegacyConfig(e)}return purgeLegacyProviderStateInConfig(),s=!0,e}export class ProviderProfilesDb{static instance=null;db;constructor(){this.db=ensureInitialized()}static async get(){return ProviderProfilesDb.instance||(ProviderProfilesDb.instance=new ProviderProfilesDb),ProviderProfilesDb.instance}}export function getProviderProfilesDbPath(){return getDatabasePath()}export function getProviderProfilesStorageBackend(){try{return ensureInitialized(),"sqlite"}catch{return"legacy"}}export function hasLegacyProviderStateInConfig(){try{const e=i();return Boolean(e.activeProvider||e.lastClaudeModel||e.lastOpenAIModel||e.lastOpenRouterModel||Object.keys(e.lastModelByProvider??{}).length>0||Object.keys(e.providerBaseUrls??{}).length>0||e.providerProfiles?.activeProfileId||Object.keys(e.providerProfiles?.profiles??{}).length>0||Object.keys(e.providerProfiles?.lastProfileIdByProvider??{}).length>0)}catch{return!1}}export function getProviderProfilesStorageMode(){return"sqlite"!==getProviderProfilesStorageBackend()?"legacy":hasLegacyProviderStateInConfig()?"sqlite-migration-pending":"sqlite-only"}export function readProviderProfilesState(){let e;try{e=ensureInitialized()}catch{return seedLegacyProfiles()}const t=e.prepare("SELECT id, provider, name, agent_name, base_url, last_model, created_at, updated_at\n FROM provider_profiles\n ORDER BY provider, created_at, id").all().map(rowToProfile).filter(e=>null!==e),n=e.prepare("SELECT provider, profile_id FROM provider_last_profile").all(),i=e.prepare(`SELECT value FROM provider_runtime_state WHERE key = '${N}'`).get();return{version:1,activeProfileId:i?.value,lastProfileIdByProvider:Object.fromEntries(n.map(e=>[e.provider,e.profile_id])),profiles:Object.fromEntries(t.map(e=>[e.id,e]))}}export function writeProviderProfilesState(e){let t;try{t=ensureInitialized()}catch{return}const n=Object.values(e.profiles??{}),i=0===n.length;t.exec("BEGIN");try{t.exec("DELETE FROM provider_last_profile"),t.exec(`DELETE FROM provider_runtime_state WHERE key = '${N}'`),t.exec("DELETE FROM provider_profiles"),i&&(t.exec(`DELETE FROM provider_runtime_state WHERE key = '${l}'`),t.exec("DELETE FROM provider_last_model"),t.exec("DELETE FROM provider_base_url"));const r=t.prepare("\n INSERT INTO provider_profiles (\n id, provider, name, agent_name, base_url, last_model, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n ");for(const e of n)r.run(e.id,e.provider,e.name,e.agentName,e.baseUrl??null,e.lastModel??null,e.createdAt,e.updatedAt);const a=t.prepare("\n INSERT INTO provider_last_profile (provider, profile_id)\n VALUES (?, ?)\n ");for(const[t,n]of Object.entries(e.lastProfileIdByProvider??{}))n&&a.run(t,n);e.activeProfileId&&t.prepare(`\n INSERT INTO provider_runtime_state (key, value)\n VALUES ('${N}', ?)\n `).run(e.activeProfileId),t.exec("COMMIT")}catch(e){throw t.exec("ROLLBACK"),e}}export function getStoredActiveProviderPreference(){const e=function(e){try{const t=ensureInitialized().prepare("SELECT value FROM provider_runtime_state WHERE key = ?").get(e);return t?.value??null}catch{return null}}(l);return null!==e?e:null}export function setStoredActiveProviderPreference(e){!function(e,t){try{const n=ensureInitialized();if(null===t)return void n.prepare("DELETE FROM provider_runtime_state WHERE key = ?").run(e);n.prepare("\n INSERT INTO provider_runtime_state (key, value)\n VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = excluded.value\n ").run(e,t)}catch{}}(l,e)}export function getStoredLastModelForProvider(e){try{const t=ensureInitialized().prepare("SELECT last_model FROM provider_last_model WHERE provider = ?").get(e);if(t&&Object.prototype.hasOwnProperty.call(t,"last_model"))return t.last_model??null}catch{return}}export function setStoredLastModelForProvider(e,t){!function(e,t){try{ensureInitialized().prepare("\n INSERT INTO provider_last_model (provider, last_model, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n last_model = excluded.last_model,\n updated_at = excluded.updated_at\n ").run(e,t,(new Date).toISOString())}catch{}}(e,t)}export function getStoredProviderBaseUrl(e){try{const t=ensureInitialized().prepare("SELECT base_url FROM provider_base_url WHERE provider = ?").get(e);if(t?.base_url?.trim())return t.base_url.trim()}catch{return}}export function setStoredProviderBaseUrl(e,t){try{ensureInitialized().prepare("\n INSERT INTO provider_base_url (provider, base_url, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n base_url = excluded.base_url,\n updated_at = excluded.updated_at\n ").run(e,t,(new Date).toISOString())}catch{}}export function clearStoredProviderBaseUrl(e){try{ensureInitialized().prepare("DELETE FROM provider_base_url WHERE provider = ?").run(e)}catch{}}
1
+ import{createRequire as e}from"module";import{randomUUID as t}from"node:crypto";import{join as n}from"path";import{getGlobalConfig as i,saveGlobalConfig as r}from"../config.js";import{getClaudeConfigHomeDir as a}from"../envUtils.js";import{getFsImplementation as o}from"../fsOperations.js";import{getSecureStorage as E}from"../secureStorage/index.js";function hasStoredCredentialForProvider(e,t){if(!e)return!1;if("openai"===t&&e.openAiOauth?.accessToken)return!0;if("claude"===t&&e.claudeAiOauth?.accessToken)return!0;if(Object.keys(e.providerProfileOauth??{}).some(e=>e.startsWith(`${t}/`)))return!0;if(e.providerApiKeys?.[t])return!0;return Object.keys(e.providerProfileApiKeys??{}).some(e=>e.startsWith(`${t}/`))}const d=e(import.meta.url);let _=null,s=!1,T=!1;const l="active_provider",N="active_profile_id",p=["claude","openai","openrouter","ollama","ollama-cloud","lmstudio","gemini-api","gemini-google","zai","minimax","deepseek","copilot"],c={claude:"main",openai:"main",openrouter:"main",ollama:"local","ollama-cloud":"main",lmstudio:"local","gemini-api":"main","gemini-google":"main",zai:"main",minimax:"main",nvidia:"main",deepseek:"main",copilot:"main"},L={claude:"claude",openai:"openai",openrouter:"openrouter",ollama:"ollama-local","ollama-cloud":"ollama-cloud",lmstudio:"lmstudio-local","gemini-api":"gemini-api","gemini-google":"gemini-google",zai:"z-ai",minimax:"minimax",nvidia:"nvidia",deepseek:"deepseek",copilot:"copilot"},u={openrouter:"https://openrouter.ai/api/v1",ollama:"http://localhost:11434/v1","ollama-cloud":"http://localhost:11434/v1",lmstudio:"http://localhost:1234/v1","gemini-api":"https://generativelanguage.googleapis.com/v1beta/openai","gemini-google":"https://generativelanguage.googleapis.com/v1beta/openai",zai:"https://api.z.ai/api/coding/paas/v4",minimax:"https://api.minimax.io/anthropic",deepseek:"https://api.deepseek.com/v1"},m={claude:"Claude",openai:"OpenAI",openrouter:"OpenRouter",ollama:"Ollama","ollama-cloud":"Ollama Cloud",lmstudio:"LM Studio","gemini-api":"Gemini API","gemini-google":"Gemini Google",zai:"Z.AI",minimax:"MiniMax",nvidia:"NVIDIA NIM",deepseek:"DeepSeek",copilot:"GitHub Copilot"},O=["openrouter","ollama","ollama-cloud","gemini-api","gemini-google","zai","minimax","deepseek"];function sanitizeProfileSegment(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"default"}function buildProfileId(e,t){return`${e}/${sanitizeProfileSegment(t)}`}function buildDefaultAgentName(e,t){const n=L[e],i=sanitizeProfileSegment(t);return i===sanitizeProfileSegment(c[e])?n:`${n}-${i}`}function tableExists(e,t){const n=e.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?").get(t);return Boolean(n)}function columnExists(e,t,n){return e.prepare(`PRAGMA table_info(${t})`).all().some(e=>e.name===n)}function migrateTeamUnitsSchema(e){e.exec("PRAGMA foreign_keys = OFF;");try{tableExists(e,"team_domains")&&e.exec("\n INSERT OR IGNORE INTO team_units (\n id, team_id, unit_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at\n )\n SELECT id, team_id, domain_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at\n FROM team_domains;\n "),tableExists(e,"team_domain_members")&&e.exec("\n INSERT OR IGNORE INTO team_unit_members (\n id, team_unit_id, agent_id, duty, priority, created_at, updated_at\n )\n SELECT id, team_domain_id, agent_id, duty, priority, created_at, updated_at\n FROM team_domain_members;\n "),tableExists(e,"orchestration_tasks")&&!columnExists(e,"orchestration_tasks","team_unit_id")&&e.exec("ALTER TABLE orchestration_tasks ADD COLUMN team_unit_id TEXT NULL;"),tableExists(e,"orchestration_tasks")&&columnExists(e,"orchestration_tasks","team_domain_id")&&columnExists(e,"orchestration_tasks","team_unit_id")&&e.exec("\n UPDATE orchestration_tasks\n SET team_unit_id = team_domain_id\n WHERE team_unit_id IS NULL AND team_domain_id IS NOT NULL;\n "),function(e){tableExists(e,"orchestration_tasks")&&columnExists(e,"orchestration_tasks","team_domain_id")&&e.exec("\n CREATE TABLE IF NOT EXISTS orchestration_tasks_v8 (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n parent_task_id TEXT NULL,\n scope_type TEXT NOT NULL,\n team_unit_id TEXT NULL,\n assigned_agent_id TEXT NULL,\n title TEXT NOT NULL,\n instructions TEXT NOT NULL,\n status TEXT NOT NULL,\n result_summary TEXT NULL,\n created_at TEXT NOT NULL,\n finished_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (parent_task_id) REFERENCES orchestration_tasks_v8(id) ON DELETE SET NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE SET NULL,\n FOREIGN KEY (assigned_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n INSERT OR REPLACE INTO orchestration_tasks_v8 (\n id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at\n )\n SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at\n FROM orchestration_tasks;\n\n DROP TABLE orchestration_tasks;\n ALTER TABLE orchestration_tasks_v8 RENAME TO orchestration_tasks;\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_run_id\n ON orchestration_tasks(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_team_unit_id\n ON orchestration_tasks(team_unit_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_assigned_agent_id\n ON orchestration_tasks(assigned_agent_id);\n ")}(e),tableExists(e,"orchestration_domain_reports")&&e.exec("\n INSERT OR IGNORE INTO orchestration_team_reports (\n id, run_id, team_unit_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at\n )\n SELECT id, run_id, team_domain_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at\n FROM orchestration_domain_reports;\n "),tableExists(e,"provider_agent_capability_rankings")&&!columnExists(e,"provider_agent_capability_rankings","team_unit_id")&&e.exec("ALTER TABLE provider_agent_capability_rankings ADD COLUMN team_unit_id TEXT NULL;"),tableExists(e,"provider_agent_capability_rankings")&&columnExists(e,"provider_agent_capability_rankings","team_domain_id")&&columnExists(e,"provider_agent_capability_rankings","team_unit_id")&&e.exec("\n UPDATE provider_agent_capability_rankings\n SET team_unit_id = team_domain_id\n WHERE team_unit_id IS NULL AND team_domain_id IS NOT NULL;\n "),function(e){tableExists(e,"provider_agent_capability_rankings")&&columnExists(e,"provider_agent_capability_rankings","team_domain_id")&&e.exec("\n CREATE TABLE IF NOT EXISTS provider_agent_capability_rankings_v8 (\n id TEXT PRIMARY KEY,\n team_unit_id TEXT NULL,\n capability TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n score REAL NOT NULL DEFAULT 0,\n reason TEXT NULL,\n source TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (team_unit_id, capability, agent_id)\n );\n\n INSERT OR REPLACE INTO provider_agent_capability_rankings_v8 (\n id, team_unit_id, capability, agent_id, score, reason, source, created_at, updated_at\n )\n SELECT id, team_unit_id, capability, agent_id, score, reason, source, created_at, updated_at\n FROM provider_agent_capability_rankings;\n\n DROP TABLE provider_agent_capability_rankings;\n ALTER TABLE provider_agent_capability_rankings_v8 RENAME TO provider_agent_capability_rankings;\n\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_team_unit\n ON provider_agent_capability_rankings(team_unit_id);\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_capability\n ON provider_agent_capability_rankings(capability);\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_agent\n ON provider_agent_capability_rankings(agent_id);\n ")}(e),e.exec("\n DROP TABLE IF EXISTS orchestration_domain_reports;\n DROP TABLE IF EXISTS team_domain_members;\n DROP TABLE IF EXISTS team_domains;\n ")}finally{e.exec("PRAGMA foreign_keys = ON;")}tableExists(e,"orchestration_tasks")&&columnExists(e,"orchestration_tasks","team_unit_id")&&e.exec("\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_team_unit_id\n ON orchestration_tasks(team_unit_id);\n "),tableExists(e,"provider_agent_capability_rankings")&&columnExists(e,"provider_agent_capability_rankings","team_unit_id")&&e.exec("\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_team_unit\n ON provider_agent_capability_rankings(team_unit_id);\n ")}function getDatabasePath(){return n(a(),"provider-state.sqlite3")}function rowToProfile(e){if(!e)return null;const t=e;return{id:t.id,provider:t.provider,name:t.name,agentName:t.agent_name,baseUrl:t.base_url??void 0,lastModel:t.last_model,createdAt:t.created_at,updatedAt:t.updated_at}}function seedLegacyProfiles(){const e=i(),t=e.providerProfiles,n={...t&&"object"==typeof t&&t.profiles?t.profiles:{}},r={...t&&"object"==typeof t&&t.lastProfileIdByProvider?t.lastProfileIdByProvider:{}},a=(()=>{try{return E().read()}catch{return null}})();for(const t of p){const i=Object.values(n).some(e=>e.provider===t),o=e.providerBaseUrls?.[t],E=e.lastModelByProvider?.[t]??null;if(!(i||e.activeProvider===t||Boolean(o)||null!==E||hasStoredCredentialForProvider(a,t))||i)continue;const d=c[t],_=buildProfileId(t,d),s=(new Date).toISOString();n[_]={id:_,provider:t,name:d,agentName:buildDefaultAgentName(t,d),baseUrl:o??u[t],lastModel:E,createdAt:s,updatedAt:s},r[t]=_}return{version:1,activeProfileId:(t&&"object"==typeof t?t.activeProfileId:void 0)??(e.activeProvider&&p.includes(e.activeProvider)?r[e.activeProvider]:void 0),lastProfileIdByProvider:r,profiles:n}}function migrateFromLegacyConfig(e){const t=i(),n=seedLegacyProfiles(),r=e.prepare("\n INSERT OR REPLACE INTO provider_profiles (\n id, provider, name, agent_name, base_url, last_model, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n "),a=e.prepare("\n INSERT INTO provider_last_profile (provider, profile_id)\n VALUES (?, ?)\n ON CONFLICT(provider) DO UPDATE SET profile_id = excluded.profile_id\n "),o=e.prepare("\n INSERT INTO provider_runtime_state (key, value)\n VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = excluded.value\n "),E=e.prepare("\n INSERT INTO provider_last_model (provider, last_model, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n last_model = excluded.last_model,\n updated_at = excluded.updated_at\n "),d=e.prepare("\n INSERT INTO provider_base_url (provider, base_url, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n base_url = excluded.base_url,\n updated_at = excluded.updated_at\n ");for(const e of Object.values(n.profiles??{}))r.run(e.id,e.provider,e.name,e.agentName,e.baseUrl??null,e.lastModel??null,e.createdAt,e.updatedAt);for(const[e,t]of Object.entries(n.lastProfileIdByProvider??{}))t&&a.run(e,t);n.activeProfileId&&o.run(N,n.activeProfileId);const _=t.activeProvider??(n.activeProfileId?n.profiles?.[n.activeProfileId]?.provider:void 0);_&&o.run(l,_);const s={claude:t.lastClaudeModel??t.lastModelByProvider?.claude??null,openai:t.lastOpenAIModel??t.lastModelByProvider?.openai??null,openrouter:t.lastOpenRouterModel??t.lastModelByProvider?.openrouter??null,ollama:t.lastModelByProvider?.ollama??null,"ollama-cloud":t.lastModelByProvider?.["ollama-cloud"]??null,"gemini-api":t.lastModelByProvider?.["gemini-api"]??null,"gemini-google":t.lastModelByProvider?.["gemini-google"]??null,zai:t.lastModelByProvider?.zai??null,minimax:t.lastModelByProvider?.minimax??null,deepseek:t.lastModelByProvider?.deepseek??null};for(const e of p)E.run(e,s[e]??null,(new Date).toISOString());for(const e of O){const n=t.providerBaseUrls?.[e];"string"==typeof n&&n.trim()&&d.run(e,n.trim(),(new Date).toISOString())}}export function purgeLegacyProviderStateInConfig(){hasLegacyProviderStateInConfig()&&r(e=>({...e,activeProvider:void 0,lastModelByProvider:{},providerBaseUrls:void 0,lastOpenAIModel:void 0,lastClaudeModel:void 0,lastOpenRouterModel:void 0,providerProfiles:void 0}))}export function finalizeProviderProfilesMigration(){ensureInitialized(),purgeLegacyProviderStateInConfig()}function ensureInitialized(){const e=function(){if(T)throw new Error("SQLite no disponible en este runtime.");if(_)return _;let e;o().mkdirSync(a(),{mode:448});try{e=d("node:sqlite")}catch(e){throw T=!0,e}return _=new e.DatabaseSync(getDatabasePath()),_}();if(s)return e;e.exec("\n PRAGMA journal_mode = WAL;\n PRAGMA foreign_keys = ON;\n PRAGMA synchronous = NORMAL;\n\n CREATE TABLE IF NOT EXISTS provider_profiles (\n id TEXT PRIMARY KEY,\n provider TEXT NOT NULL,\n name TEXT NOT NULL,\n agent_name TEXT NOT NULL,\n base_url TEXT NULL,\n last_model TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_last_profile (\n provider TEXT PRIMARY KEY,\n profile_id TEXT NOT NULL,\n FOREIGN KEY (profile_id) REFERENCES provider_profiles(id) ON DELETE CASCADE\n );\n\n CREATE TABLE IF NOT EXISTS provider_runtime_state (\n key TEXT PRIMARY KEY,\n value TEXT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_last_model (\n provider TEXT PRIMARY KEY,\n last_model TEXT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_base_url (\n provider TEXT PRIMARY KEY,\n base_url TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_workspaces (\n id TEXT PRIMARY KEY,\n provider TEXT NOT NULL UNIQUE,\n display_name TEXT NOT NULL,\n domain_focus TEXT NULL,\n is_enabled INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_agents (\n id TEXT PRIMARY KEY,\n workspace_id TEXT NOT NULL,\n profile_id TEXT NOT NULL,\n name TEXT NOT NULL,\n role_kind TEXT NULL,\n system_prompt TEXT NULL,\n model_override TEXT NULL,\n tool_policy TEXT NULL,\n autonomy_level TEXT NULL,\n is_orchestrator INTEGER NOT NULL DEFAULT 0,\n is_enabled INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (workspace_id) REFERENCES provider_workspaces(id) ON DELETE CASCADE,\n FOREIGN KEY (profile_id) REFERENCES provider_profiles(id) ON DELETE CASCADE,\n UNIQUE (workspace_id, name)\n );\n\n CREATE INDEX IF NOT EXISTS idx_provider_agents_workspace_id\n ON provider_agents(workspace_id);\n CREATE INDEX IF NOT EXISTS idx_provider_agents_profile_id\n ON provider_agents(profile_id);\n\n CREATE TABLE IF NOT EXISTS provider_agent_capabilities (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL,\n capability TEXT NOT NULL,\n weight REAL NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (agent_id, capability)\n );\n\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capabilities_agent_id\n ON provider_agent_capabilities(agent_id);\n\n CREATE TABLE IF NOT EXISTS teams (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n description TEXT NULL,\n global_orchestrator_agent_id TEXT NULL,\n is_enabled INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (global_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE TABLE IF NOT EXISTS team_units (\n id TEXT PRIMARY KEY,\n team_id TEXT NOT NULL,\n unit_name TEXT NOT NULL,\n workspace_id TEXT NULL,\n local_orchestrator_agent_id TEXT NULL,\n lead_agent_id TEXT NULL,\n selection_mode TEXT NOT NULL DEFAULT 'manual',\n required INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE,\n FOREIGN KEY (workspace_id) REFERENCES provider_workspaces(id) ON DELETE SET NULL,\n FOREIGN KEY (local_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n FOREIGN KEY (lead_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n UNIQUE (team_id, unit_name)\n );\n\n CREATE INDEX IF NOT EXISTS idx_team_units_team_id\n ON team_units(team_id);\n CREATE INDEX IF NOT EXISTS idx_team_units_workspace_id\n ON team_units(workspace_id);\n CREATE INDEX IF NOT EXISTS idx_team_units_local_orchestrator_agent_id\n ON team_units(local_orchestrator_agent_id);\n CREATE INDEX IF NOT EXISTS idx_team_units_lead_agent_id\n ON team_units(lead_agent_id);\n\n CREATE TABLE IF NOT EXISTS team_unit_members (\n id TEXT PRIMARY KEY,\n team_unit_id TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n duty TEXT NULL,\n priority INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (team_unit_id, agent_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_team_unit_members_team_unit_id\n ON team_unit_members(team_unit_id);\n CREATE INDEX IF NOT EXISTS idx_team_unit_members_agent_id\n ON team_unit_members(agent_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_runs (\n id TEXT PRIMARY KEY,\n team_id TEXT NOT NULL,\n goal TEXT NOT NULL,\n global_orchestrator_agent_id TEXT NULL,\n status TEXT NOT NULL,\n created_at TEXT NOT NULL,\n started_at TEXT NULL,\n finished_at TEXT NULL,\n FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE,\n FOREIGN KEY (global_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_runs_team_id\n ON orchestration_runs(team_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_runs_status\n ON orchestration_runs(status);\n\n CREATE TABLE IF NOT EXISTS orchestration_tasks (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n parent_task_id TEXT NULL,\n scope_type TEXT NOT NULL,\n team_unit_id TEXT NULL,\n assigned_agent_id TEXT NULL,\n title TEXT NOT NULL,\n instructions TEXT NOT NULL,\n status TEXT NOT NULL,\n result_summary TEXT NULL,\n created_at TEXT NOT NULL,\n finished_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (parent_task_id) REFERENCES orchestration_tasks(id) ON DELETE SET NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE SET NULL,\n FOREIGN KEY (assigned_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_run_id\n ON orchestration_tasks(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_assigned_agent_id\n ON orchestration_tasks(assigned_agent_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_messages (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n task_id TEXT NULL,\n from_agent_id TEXT NULL,\n to_agent_id TEXT NULL,\n message_type TEXT NOT NULL,\n content TEXT NOT NULL,\n created_at TEXT NOT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (task_id) REFERENCES orchestration_tasks(id) ON DELETE SET NULL,\n FOREIGN KEY (from_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n FOREIGN KEY (to_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_messages_run_id\n ON orchestration_messages(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_messages_task_id\n ON orchestration_messages(task_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_task_results (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n task_id TEXT NOT NULL,\n agent_id TEXT NULL,\n result_type TEXT NOT NULL,\n status TEXT NOT NULL,\n summary TEXT NULL,\n content TEXT NULL,\n metadata_json TEXT NULL,\n created_at TEXT NOT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (task_id) REFERENCES orchestration_tasks(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_task_results_run_id\n ON orchestration_task_results(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_task_results_task_id\n ON orchestration_task_results(task_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_task_results_agent_id\n ON orchestration_task_results(agent_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_team_reports (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n team_unit_id TEXT NOT NULL,\n local_orchestrator_agent_id TEXT NULL,\n status TEXT NOT NULL,\n summary TEXT NOT NULL,\n blockers TEXT NULL,\n output TEXT NULL,\n metrics_json TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n submitted_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (local_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n UNIQUE (run_id, team_unit_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_team_reports_run_id\n ON orchestration_team_reports(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_team_reports_team_unit_id\n ON orchestration_team_reports(team_unit_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_run_reports (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL UNIQUE,\n status TEXT NOT NULL,\n summary TEXT NOT NULL,\n output TEXT NULL,\n risks TEXT NULL,\n next_steps TEXT NULL,\n metrics_json TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n submitted_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_run_reports_run_id\n ON orchestration_run_reports(run_id);\n\n CREATE TABLE IF NOT EXISTS provider_agent_capability_rankings (\n id TEXT PRIMARY KEY,\n team_unit_id TEXT NULL,\n capability TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n score REAL NOT NULL DEFAULT 0,\n reason TEXT NULL,\n source TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (team_unit_id, capability, agent_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_capability\n ON provider_agent_capability_rankings(capability);\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_agent\n ON provider_agent_capability_rankings(agent_id);\n\n CREATE TABLE IF NOT EXISTS secure_storage (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS projects (\n path TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n created_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS permission_rules (\n id TEXT PRIMARY KEY,\n scope TEXT NOT NULL,\n scope_path TEXT NULL,\n tool_name TEXT NOT NULL,\n behavior TEXT NOT NULL,\n created_at TEXT NOT NULL,\n expires_at TEXT NULL,\n UNIQUE (scope, scope_path, tool_name)\n );\n\n CREATE INDEX IF NOT EXISTS idx_permission_rules_scope\n ON permission_rules(scope, scope_path);\n CREATE INDEX IF NOT EXISTS idx_permission_rules_tool_name\n ON permission_rules(tool_name);\n\n CREATE TABLE IF NOT EXISTS permission_mode_config (\n id TEXT PRIMARY KEY,\n scope TEXT NOT NULL,\n scope_path TEXT NULL,\n mode TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE (scope, scope_path)\n );\n\n CREATE TABLE IF NOT EXISTS trusted_directories (\n path TEXT PRIMARY KEY,\n trust_level TEXT NOT NULL DEFAULT 'full',\n created_at TEXT NOT NULL\n );\n "),migrateTeamUnitsSchema(e);const n=e.prepare("PRAGMA user_version").get();(n?.user_version??0)<8&&e.exec("PRAGMA user_version = 8"),function(e){const n=(new Date).toISOString(),i=e.prepare("\n INSERT OR IGNORE INTO provider_workspaces (\n id, provider, display_name, domain_focus, is_enabled, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n ");for(const e of p)i.run(t(),e,m[e]??e,null,1,n,n)}(e);const i=e.prepare("SELECT COUNT(*) AS count FROM provider_profiles").get();if(0===(i?.count??0))migrateFromLegacyConfig(e);else{const t=e.prepare("SELECT COUNT(*) AS count FROM provider_last_model").get();0===(t?.count??0)&&migrateFromLegacyConfig(e);const n=e.prepare("SELECT COUNT(*) AS count FROM provider_base_url").get();0===(n?.count??0)&&migrateFromLegacyConfig(e)}return purgeLegacyProviderStateInConfig(),s=!0,e}export class ProviderProfilesDb{static instance=null;db;constructor(){this.db=ensureInitialized()}static async get(){return ProviderProfilesDb.instance||(ProviderProfilesDb.instance=new ProviderProfilesDb),ProviderProfilesDb.instance}}export function getProviderProfilesDbPath(){return getDatabasePath()}export function getProviderProfilesStorageBackend(){try{return ensureInitialized(),"sqlite"}catch{return"legacy"}}export function hasLegacyProviderStateInConfig(){try{const e=i();return Boolean(e.activeProvider||e.lastClaudeModel||e.lastOpenAIModel||e.lastOpenRouterModel||Object.keys(e.lastModelByProvider??{}).length>0||Object.keys(e.providerBaseUrls??{}).length>0||e.providerProfiles?.activeProfileId||Object.keys(e.providerProfiles?.profiles??{}).length>0||Object.keys(e.providerProfiles?.lastProfileIdByProvider??{}).length>0)}catch{return!1}}export function getProviderProfilesStorageMode(){return"sqlite"!==getProviderProfilesStorageBackend()?"legacy":hasLegacyProviderStateInConfig()?"sqlite-migration-pending":"sqlite-only"}export function readProviderProfilesState(){let e;try{e=ensureInitialized()}catch{return seedLegacyProfiles()}const t=e.prepare("SELECT id, provider, name, agent_name, base_url, last_model, created_at, updated_at\n FROM provider_profiles\n ORDER BY provider, created_at, id").all().map(rowToProfile).filter(e=>null!==e),n=e.prepare("SELECT provider, profile_id FROM provider_last_profile").all(),i=e.prepare(`SELECT value FROM provider_runtime_state WHERE key = '${N}'`).get();return{version:1,activeProfileId:i?.value,lastProfileIdByProvider:Object.fromEntries(n.map(e=>[e.provider,e.profile_id])),profiles:Object.fromEntries(t.map(e=>[e.id,e]))}}export function writeProviderProfilesState(e){let t;try{t=ensureInitialized()}catch{return}const n=Object.values(e.profiles??{}),i=0===n.length;t.exec("BEGIN");try{t.exec("DELETE FROM provider_last_profile"),t.exec(`DELETE FROM provider_runtime_state WHERE key = '${N}'`),t.exec("DELETE FROM provider_profiles"),i&&(t.exec(`DELETE FROM provider_runtime_state WHERE key = '${l}'`),t.exec("DELETE FROM provider_last_model"),t.exec("DELETE FROM provider_base_url"));const r=t.prepare("\n INSERT INTO provider_profiles (\n id, provider, name, agent_name, base_url, last_model, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n ");for(const e of n)r.run(e.id,e.provider,e.name,e.agentName,e.baseUrl??null,e.lastModel??null,e.createdAt,e.updatedAt);const a=t.prepare("\n INSERT INTO provider_last_profile (provider, profile_id)\n VALUES (?, ?)\n ");for(const[t,n]of Object.entries(e.lastProfileIdByProvider??{}))n&&a.run(t,n);e.activeProfileId&&t.prepare(`\n INSERT INTO provider_runtime_state (key, value)\n VALUES ('${N}', ?)\n `).run(e.activeProfileId),t.exec("COMMIT")}catch(e){throw t.exec("ROLLBACK"),e}}export function getStoredActiveProviderPreference(){const e=function(e){try{const t=ensureInitialized().prepare("SELECT value FROM provider_runtime_state WHERE key = ?").get(e);return t?.value??null}catch{return null}}(l);return null!==e?e:null}export function setStoredActiveProviderPreference(e){!function(e,t){try{const n=ensureInitialized();if(null===t)return void n.prepare("DELETE FROM provider_runtime_state WHERE key = ?").run(e);n.prepare("\n INSERT INTO provider_runtime_state (key, value)\n VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = excluded.value\n ").run(e,t)}catch{}}(l,e)}export function getStoredLastModelForProvider(e){try{const t=ensureInitialized().prepare("SELECT last_model FROM provider_last_model WHERE provider = ?").get(e);if(t&&Object.prototype.hasOwnProperty.call(t,"last_model"))return t.last_model??null}catch{return}}export function setStoredLastModelForProvider(e,t){!function(e,t){try{ensureInitialized().prepare("\n INSERT INTO provider_last_model (provider, last_model, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n last_model = excluded.last_model,\n updated_at = excluded.updated_at\n ").run(e,t,(new Date).toISOString())}catch{}}(e,t)}export function getStoredProviderBaseUrl(e){try{const t=ensureInitialized().prepare("SELECT base_url FROM provider_base_url WHERE provider = ?").get(e);if(t?.base_url?.trim())return t.base_url.trim()}catch{return}}export function setStoredProviderBaseUrl(e,t){try{ensureInitialized().prepare("\n INSERT INTO provider_base_url (provider, base_url, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n base_url = excluded.base_url,\n updated_at = excluded.updated_at\n ").run(e,t,(new Date).toISOString())}catch{}}export function clearStoredProviderBaseUrl(e){try{ensureInitialized().prepare("DELETE FROM provider_base_url WHERE provider = ?").run(e)}catch{}}
@@ -1 +1 @@
1
- import{A as e,Aa as r,Ba as i,C as a,Ca as o,Da as l,Ea as u,J as h,P as p,Q as b,a as g,aa as w,c as d,d as v,f,h as E,i as m,j as y,k,l as O,m as T,o as C,pa as A,q as I,r as P,s as S,t as M,wa as N,xa as D,ya as W,za as L}from"./chunk-VAB2VXFI.js";var _="Service workers are disabled or not supported by this browser",x=class{serviceWorker;worker;registration;events;constructor(e,r){if(this.serviceWorker=e,e){let i=null,a=new v;this.worker=new d(e=>(null!==i&&e.next(i),a.subscribe(r=>e.next(r))));let s=()=>{let{controller:r}=e;null!==r&&(i=r,a.next(i))};e.addEventListener("controllerchange",s),s(),this.registration=this.worker.pipe(k(()=>e.getRegistration()));let o=new v;this.events=o.asObservable();let c=e=>{let{data:r}=e;r?.type&&o.next(r)};e.addEventListener("message",c),r?.get(b,null,{optional:!0})?.onDestroy(()=>{e.removeEventListener("controllerchange",s),e.removeEventListener("message",c)})}else this.worker=this.events=this.registration=new d(e=>e.error(new O(5601,!1)))}postMessage(e,r){return new Promise(i=>{this.worker.pipe(y(1)).subscribe(a=>{a.postMessage(g({action:e},r)),i()})})}postMessageWithOperation(e,r,i){let a=this.waitForOperationCompleted(i),o=this.postMessage(e,r);return Promise.all([o,a]).then(([,e])=>e)}generateNonce(){return Math.round(1e7*Math.random())}eventsOfType(e){let r;return r="string"==typeof e?r=>r.type===e:r=>e.includes(r.type),this.events.pipe(m(r))}nextEventOfType(e){return this.eventsOfType(e).pipe(y(1))}waitForOperationCompleted(e){return new Promise((r,i)=>{this.eventsOfType("OPERATION_COMPLETED").pipe(m(r=>r.nonce===e),y(1),f(e=>{if(void 0!==e.result)return e.result;throw new Error(e.error)})).subscribe({next:r,error:i})})}get isEnabled(){return!!this.serviceWorker}},V=(()=>{class n{sw;messages;notificationClicks;subscription;get isEnabled(){return this.sw.isEnabled}pushManager=null;subscriptionChanges=new v;constructor(e){if(this.sw=e,!e.isEnabled)return this.messages=E,this.notificationClicks=E,void(this.subscription=E);this.messages=this.sw.eventsOfType("PUSH").pipe(f(e=>e.data)),this.notificationClicks=this.sw.eventsOfType("NOTIFICATION_CLICK").pipe(f(e=>e.data)),this.pushManager=this.sw.registration.pipe(f(e=>e.pushManager));let r=this.pushManager.pipe(k(e=>e.getSubscription()));this.subscription=new d(e=>{let i=r.subscribe(e),a=this.subscriptionChanges.subscribe(e);return()=>{i.unsubscribe(),a.unsubscribe()}})}requestSubscription(e){if(!this.sw.isEnabled||null===this.pushManager)return Promise.reject(new Error(_));let r={userVisibleOnly:!0},i=this.decodeBase64(e.serverPublicKey.replace(/_/g,"/").replace(/-/g,"+")),a=new Uint8Array(new ArrayBuffer(i.length));for(let e=0;e<i.length;e++)a[e]=i.charCodeAt(e);return r.applicationServerKey=a,new Promise((e,i)=>{this.pushManager.pipe(k(e=>e.subscribe(r)),y(1)).subscribe({next:r=>{this.subscriptionChanges.next(r),e(r)},error:i})})}unsubscribe(){if(!this.sw.isEnabled)return Promise.reject(new Error(_));let t=e=>{if(null===e)throw new O(5602,!1);return e.unsubscribe().then(e=>{if(!e)throw new O(5603,!1);this.subscriptionChanges.next(null)})};return new Promise((e,r)=>{this.subscription.pipe(y(1),k(t)).subscribe({next:e,error:r})})}decodeBase64(e){return atob(e)}static ɵfac=function(e){return new(e||n)(P(x))};static ɵprov=C({token:n,factory:n.ɵfac})}return n})(),F=(()=>{class n{sw;versionUpdates;unrecoverable;get isEnabled(){return this.sw.isEnabled}constructor(e){if(this.sw=e,!e.isEnabled)return this.versionUpdates=E,void(this.unrecoverable=E);this.versionUpdates=this.sw.eventsOfType(["VERSION_DETECTED","VERSION_INSTALLATION_FAILED","VERSION_READY","NO_NEW_VERSION_DETECTED"]),this.unrecoverable=this.sw.eventsOfType("UNRECOVERABLE_STATE")}checkForUpdate(){if(!this.sw.isEnabled)return Promise.reject(new Error(_));let e=this.sw.generateNonce();return this.sw.postMessageWithOperation("CHECK_FOR_UPDATES",{nonce:e},e)}activateUpdate(){if(!this.sw.isEnabled)return Promise.reject(new O(5601,!1));let e=this.sw.generateNonce();return this.sw.postMessageWithOperation("ACTIVATE_UPDATE",{nonce:e},e)}static ɵfac=function(e){return new(e||n)(P(x))};static ɵprov=C({token:n,factory:n.ɵfac})}return n})(),R=new I("");function X(){let e=S(U);if(!("serviceWorker"in navigator)||!1===e.enabled)return;let r=S(R),i=S(a),o=S(b);i.runOutsideAngular(()=>{let e=navigator.serviceWorker,s=()=>e.controller?.postMessage({action:"INITIALIZE"});e.addEventListener("controllerchange",s),o.onDestroy(()=>{e.removeEventListener("controllerchange",s)})}),i.runOutsideAngular(()=>{let i,{registrationStrategy:a}=e;if("function"==typeof a)i=new Promise(e=>a().subscribe(()=>e()));else{let[e,...r]=(a||"registerWhenStable:30000").split(":");switch(e){case"registerImmediately":i=Promise.resolve();break;case"registerWithDelay":i=q(+r[0]||0);break;case"registerWhenStable":i=Promise.race([o.whenStable(),q(+r[0])]);break;default:throw new O(5600,!1)}}i.then(()=>{o.destroyed||navigator.serviceWorker.register(r,{scope:e.scope}).catch(e=>console.error(T(5604,!1)))})})}function q(e){return new Promise(r=>setTimeout(r,e))}function ee(e,r){return new x(!1!==e.enabled?navigator.serviceWorker:void 0,r)}var U=class{enabled;scope;registrationStrategy};N(class n{constructor(){this.auth=S(l),this.socket=S(u)}ngOnInit(){this.auth.hasToken()&&this.socket.connect()}static{this.ɵfac=function(e){return new(e||n)}}static{this.ɵcmp=h({type:n,selectors:[["cx-root"]],decls:1,vars:0,template:function(e,r){1&e&&w(0,"router-outlet")},dependencies:[L],encapsulation:2,changeDetection:0})}},{providers:[i([{path:"",redirectTo:"chat",pathMatch:"full"},{path:"login",loadComponent:()=>import("./chunk-NFYBHCXF.js").then(e=>e.LoginComponent)},{path:"chat",canActivate:[()=>{let e=S(l),i=S(r);return!!e.hasToken()||(i.navigate(["/login"]),!1)}],loadComponent:()=>import("./chunk-AMCDNAIG.js").then(e=>e.ChatComponent)},{path:"**",redirectTo:"chat"}],o()),D(W()),function(r,i={}){return M([V,F,{provide:R,useValue:r},{provide:U,useValue:i},{provide:x,useFactory:ee,deps:[U,e]},p(X)])}("ngsw-worker.js",{enabled:!A(),registrationStrategy:"registerWhenStable:30000"})]}).catch(e=>console.error("[webapp] bootstrap error",e));
1
+ import{A as e,Aa as r,Ba as i,C as a,Ca as o,Da as l,Ea as u,J as h,P as p,Q as b,a as g,aa as w,c as d,d as v,f as E,h as f,i as m,j as y,k as O,l as k,m as T,o as C,pa as A,q as I,r as P,s as S,t as M,wa as N,xa as D,ya as W,za as L}from"./chunk-VAB2VXFI.js";var _="Service workers are disabled or not supported by this browser",x=class{serviceWorker;worker;registration;events;constructor(e,r){if(this.serviceWorker=e,e){let i=null,a=new v;this.worker=new d(e=>(null!==i&&e.next(i),a.subscribe(r=>e.next(r))));let s=()=>{let{controller:r}=e;null!==r&&(i=r,a.next(i))};e.addEventListener("controllerchange",s),s(),this.registration=this.worker.pipe(O(()=>e.getRegistration()));let o=new v;this.events=o.asObservable();let c=e=>{let{data:r}=e;r?.type&&o.next(r)};e.addEventListener("message",c),r?.get(b,null,{optional:!0})?.onDestroy(()=>{e.removeEventListener("controllerchange",s),e.removeEventListener("message",c)})}else this.worker=this.events=this.registration=new d(e=>e.error(new k(5601,!1)))}postMessage(e,r){return new Promise(i=>{this.worker.pipe(y(1)).subscribe(a=>{a.postMessage(g({action:e},r)),i()})})}postMessageWithOperation(e,r,i){let a=this.waitForOperationCompleted(i),o=this.postMessage(e,r);return Promise.all([o,a]).then(([,e])=>e)}generateNonce(){return Math.round(1e7*Math.random())}eventsOfType(e){let r;return r="string"==typeof e?r=>r.type===e:r=>e.includes(r.type),this.events.pipe(m(r))}nextEventOfType(e){return this.eventsOfType(e).pipe(y(1))}waitForOperationCompleted(e){return new Promise((r,i)=>{this.eventsOfType("OPERATION_COMPLETED").pipe(m(r=>r.nonce===e),y(1),E(e=>{if(void 0!==e.result)return e.result;throw new Error(e.error)})).subscribe({next:r,error:i})})}get isEnabled(){return!!this.serviceWorker}},V=(()=>{class n{sw;messages;notificationClicks;subscription;get isEnabled(){return this.sw.isEnabled}pushManager=null;subscriptionChanges=new v;constructor(e){if(this.sw=e,!e.isEnabled)return this.messages=f,this.notificationClicks=f,void(this.subscription=f);this.messages=this.sw.eventsOfType("PUSH").pipe(E(e=>e.data)),this.notificationClicks=this.sw.eventsOfType("NOTIFICATION_CLICK").pipe(E(e=>e.data)),this.pushManager=this.sw.registration.pipe(E(e=>e.pushManager));let r=this.pushManager.pipe(O(e=>e.getSubscription()));this.subscription=new d(e=>{let i=r.subscribe(e),a=this.subscriptionChanges.subscribe(e);return()=>{i.unsubscribe(),a.unsubscribe()}})}requestSubscription(e){if(!this.sw.isEnabled||null===this.pushManager)return Promise.reject(new Error(_));let r={userVisibleOnly:!0},i=this.decodeBase64(e.serverPublicKey.replace(/_/g,"/").replace(/-/g,"+")),a=new Uint8Array(new ArrayBuffer(i.length));for(let e=0;e<i.length;e++)a[e]=i.charCodeAt(e);return r.applicationServerKey=a,new Promise((e,i)=>{this.pushManager.pipe(O(e=>e.subscribe(r)),y(1)).subscribe({next:r=>{this.subscriptionChanges.next(r),e(r)},error:i})})}unsubscribe(){if(!this.sw.isEnabled)return Promise.reject(new Error(_));let t=e=>{if(null===e)throw new k(5602,!1);return e.unsubscribe().then(e=>{if(!e)throw new k(5603,!1);this.subscriptionChanges.next(null)})};return new Promise((e,r)=>{this.subscription.pipe(y(1),O(t)).subscribe({next:e,error:r})})}decodeBase64(e){return atob(e)}static ɵfac=function(e){return new(e||n)(P(x))};static ɵprov=C({token:n,factory:n.ɵfac})}return n})(),F=(()=>{class n{sw;versionUpdates;unrecoverable;get isEnabled(){return this.sw.isEnabled}constructor(e){if(this.sw=e,!e.isEnabled)return this.versionUpdates=f,void(this.unrecoverable=f);this.versionUpdates=this.sw.eventsOfType(["VERSION_DETECTED","VERSION_INSTALLATION_FAILED","VERSION_READY","NO_NEW_VERSION_DETECTED"]),this.unrecoverable=this.sw.eventsOfType("UNRECOVERABLE_STATE")}checkForUpdate(){if(!this.sw.isEnabled)return Promise.reject(new Error(_));let e=this.sw.generateNonce();return this.sw.postMessageWithOperation("CHECK_FOR_UPDATES",{nonce:e},e)}activateUpdate(){if(!this.sw.isEnabled)return Promise.reject(new k(5601,!1));let e=this.sw.generateNonce();return this.sw.postMessageWithOperation("ACTIVATE_UPDATE",{nonce:e},e)}static ɵfac=function(e){return new(e||n)(P(x))};static ɵprov=C({token:n,factory:n.ɵfac})}return n})(),R=new I("");function X(){let e=S(U);if(!("serviceWorker"in navigator)||!1===e.enabled)return;let r=S(R),i=S(a),o=S(b);i.runOutsideAngular(()=>{let e=navigator.serviceWorker,s=()=>e.controller?.postMessage({action:"INITIALIZE"});e.addEventListener("controllerchange",s),o.onDestroy(()=>{e.removeEventListener("controllerchange",s)})}),i.runOutsideAngular(()=>{let i,{registrationStrategy:a}=e;if("function"==typeof a)i=new Promise(e=>a().subscribe(()=>e()));else{let[e,...r]=(a||"registerWhenStable:30000").split(":");switch(e){case"registerImmediately":i=Promise.resolve();break;case"registerWithDelay":i=q(+r[0]||0);break;case"registerWhenStable":i=Promise.race([o.whenStable(),q(+r[0])]);break;default:throw new k(5600,!1)}}i.then(()=>{o.destroyed||navigator.serviceWorker.register(r,{scope:e.scope}).catch(e=>console.error(T(5604,!1)))})})}function q(e){return new Promise(r=>setTimeout(r,e))}function ee(e,r){return new x(!1!==e.enabled?navigator.serviceWorker:void 0,r)}var U=class{enabled;scope;registrationStrategy};N(class n{constructor(){this.auth=S(l),this.socket=S(u)}ngOnInit(){this.auth.hasToken()&&this.socket.connect()}static{this.ɵfac=function(e){return new(e||n)}}static{this.ɵcmp=h({type:n,selectors:[["cx-root"]],decls:1,vars:0,template:function(e,r){1&e&&w(0,"router-outlet")},dependencies:[L],encapsulation:2,changeDetection:0})}},{providers:[i([{path:"",redirectTo:"chat",pathMatch:"full"},{path:"login",loadComponent:()=>import("./chunk-NFYBHCXF.js").then(e=>e.LoginComponent)},{path:"chat",canActivate:[()=>{let e=S(l),i=S(r);return!!e.hasToken()||(i.navigate(["/login"]),!1)}],loadComponent:()=>import("./chunk-AMCDNAIG.js").then(e=>e.ChatComponent)},{path:"**",redirectTo:"chat"}],o()),D(W()),function(r,i={}){return M([V,F,{provide:R,useValue:r},{provide:U,useValue:i},{provide:x,useFactory:ee,deps:[U,e]},p(X)])}("ngsw-worker.js",{enabled:!A(),registrationStrategy:"registerWhenStable:30000"})]}).catch(e=>console.error("[webapp] bootstrap error",e));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iaforged/context-code",
3
- "version": "2.4.4",
3
+ "version": "2.4.7",
4
4
  "description": "Context Code es un asistente de desarrollo para la terminal. Puede revisar tu proyecto, editar archivos, ejecutar comandos y apoyarte en tareas reales de programacion.",
5
5
  "author": "Context AI",
6
6
  "license": "MIT",